Browse Source

fixbug for kcp

ithewei 3 years ago
parent
commit
4ddf20e0df
4 changed files with 96 additions and 53 deletions
  1. 1 0
      event/hevent.c
  2. 32 0
      event/hloop.h
  3. 7 2
      event/kcp/hkcp.c
  4. 56 51
      examples/nc.c

+ 1 - 0
event/hevent.c

@@ -330,6 +330,7 @@ void hio_handle_read(hio_t* io, void* buf, int readbytes) {
 #if WITH_KCP
     if (io->io_type == HIO_TYPE_KCP) {
         hio_read_kcp(io, buf, readbytes);
+        io->readbuf.head = io->readbuf.tail = 0;
         return;
     }
 #endif

+ 32 - 0
event/hloop.h

@@ -691,6 +691,38 @@ typedef struct kcp_setting_s {
 #endif
 } kcp_setting_t;
 
+HV_INLINE void kcp_setting_init_with_normal_mode(kcp_setting_t* setting) {
+    memset(setting, 0, sizeof(kcp_setting_t));
+    setting->nodelay = 0;
+    setting->interval = 40;
+    setting->fastresend = 0;
+    setting->nocwnd = 0;
+}
+
+HV_INLINE void kcp_setting_init_with_fast_mode(kcp_setting_t* setting) {
+    memset(setting, 0, sizeof(kcp_setting_t));
+    setting->nodelay = 0;
+    setting->interval = 30;
+    setting->fastresend = 2;
+    setting->nocwnd = 1;
+}
+
+HV_INLINE void kcp_setting_init_with_fast2_mode(kcp_setting_t* setting) {
+    memset(setting, 0, sizeof(kcp_setting_t));
+    setting->nodelay = 1;
+    setting->interval = 20;
+    setting->fastresend = 2;
+    setting->nocwnd = 1;
+}
+
+HV_INLINE void kcp_setting_init_with_fast3_mode(kcp_setting_t* setting) {
+    memset(setting, 0, sizeof(kcp_setting_t));
+    setting->nodelay = 1;
+    setting->interval = 10;
+    setting->fastresend = 2;
+    setting->nocwnd = 1;
+}
+
 // @see examples/udp_echo_server.c => #define TEST_KCP 1
 HV_EXPORT int hio_set_kcp(hio_t* io, kcp_setting_t* setting DEFAULT(NULL));
 #endif

+ 7 - 2
event/kcp/hkcp.c

@@ -78,6 +78,7 @@ kcp_t* hio_get_kcp(hio_t* io, uint32_t conv) {
 int hio_write_kcp(hio_t* io, const void* buf, size_t len) {
     IUINT32 conv = io->kcp_setting ? io->kcp_setting->conv : 0;
     kcp_t* kcp = hio_get_kcp(io, conv);
+    // printf("hio_write_kcp conv=%u=%u\n", conv, kcp->conv);
     int nsend = ikcp_send(kcp->ikcp, (const char*)buf, len);
     // printf("ikcp_send len=%d nsend=%d\n", (int)len, nsend);
     if (nsend < 0) {
@@ -91,18 +92,22 @@ int hio_write_kcp(hio_t* io, const void* buf, size_t len) {
 int hio_read_kcp (hio_t* io, void* buf, int readbytes) {
     IUINT32 conv = ikcp_getconv(buf);
     kcp_t* kcp = hio_get_kcp(io, conv);
+    // printf("hio_read_kcp conv=%u=%u\n", conv, kcp->conv);
     if (kcp->conv != conv) {
         hloge("recv invalid kcp packet!");
         hio_close_rudp(io, io->peeraddr);
         return -1;
     }
     // printf("ikcp_input len=%d\n", readbytes);
-    ikcp_input(kcp->ikcp, (const char*)buf, readbytes);
+    int ret = ikcp_input(kcp->ikcp, (const char*)buf, readbytes);
+    // printf("ikcp_input ret=%d\n", ret);
+    if (ret != 0) {
+        return 0;
+    }
     if (kcp->readbuf.base == NULL || kcp->readbuf.len == 0) {
         kcp->readbuf.len = DEFAULT_KCP_READ_BUFSIZE;
         HV_ALLOC(kcp->readbuf.base, kcp->readbuf.len);
     }
-    int ret = 0;
     while (1) {
         int nrecv = ikcp_recv(kcp->ikcp, kcp->readbuf.base, kcp->readbuf.len);
         // printf("ikcp_recv nrecv=%d\n", nrecv);

+ 56 - 51
examples/nc.c

@@ -12,42 +12,43 @@
  *          > [Enter]
  */
 
-#include "hloop.h"
-#include "hbase.h"
-#include "hsocket.h"
-#include "hssl.h"
-
 /*
- * @test    ssl_client
- * #define  TEST_SSL 1
+ * @test    udp client
+ * @build   ./configure && make examples
+ * @client  bin/nc -u 127.0.0.1 1234
  *
+ */
+
+/*
+ * @test    ssl client
  * @build   ./configure --with-openssl && make clean && make
+ * @client  bin/nc -s 127.0.0.1 1234
  *
  */
-#define TEST_SSL 0
 
 /*
- * @test    kcp_client
- * #define  TEST_KCP 1
- *
+ * @test    kcp client
  * @build   ./configure --with-kcp && make clean && make
- * @server  bin/udp_echo_server 1234
- * @client  bin/nc -u 127.0.0.1 1234
+ * @client  bin/nc -k 127.0.0.1 1234
  *
  */
-#define TEST_KCP 0
+
+#include "hloop.h"
+#include "hbase.h"
+#include "hsocket.h"
+#include "hssl.h"
 
 #define RECV_BUFSIZE    8192
 static char recvbuf[RECV_BUFSIZE];
 
-// 1:tcp 2:udp
-int protocol = 1;
+static char protocol = 't';
+static const char* protocolname = "tcp";
 // for stdin
-hio_t*      stdinio = NULL;
+static hio_t* stdinio = NULL;
 // for socket
-hio_t*      sockio = NULL;
+static hio_t* sockio = NULL;
 
-int verbose = 0;
+static int verbose = 0;
 
 static void send_heartbeat(hio_t* io) {
     static char buf[] = "PING\r\n";
@@ -125,12 +126,10 @@ static void on_stdin(hio_t* io, void* buf, int readbytes) {
 
     hio_write(sockio, buf, readbytes);
 
-#if TEST_KCP
     if (strncmp(str, "CLOSE", 5) == 0) {
         printf("call hio_close\n");
         hio_close(sockio);
     }
-#endif
 }
 
 static void on_close(hio_t* io) {
@@ -156,27 +155,28 @@ static void on_connect(hio_t* io) {
 int main(int argc, char** argv) {
     if (argc < 3) {
         printf("\
-Usage: nc [-ut] host port\n\
+Usage: nc [-tusk] host port\n\
 Options:\n\
   -t        Use tcp protocol (default)\n\
   -u        Use udp protocol\n\
+  -s        Use ssl protocol\n\
+  -k        Use kcp protocol\n\
 Examples: nc 127.0.0.1 80\n\
           nc -u 127.0.0.1 80\n");
         return -10;
     }
 
     int index = 1;
-    const char* protocolname;
     if (argv[1][0] == '-') {
-        ++index;
-        if (argv[1][1] == 't') {
-            protocol = 1;
-            protocolname = "tcp";
-        }
-        else if (argv[1][1] == 'u') {
-            protocol = 2;
-            protocolname = "udp";
+        protocol = argv[1][1];
+        switch(protocol) {
+        case 't': protocolname = "tcp"; break;
+        case 'u': protocolname = "udp"; break;
+        case 's': protocolname = "ssl"; break;
+        case 'k': protocolname = "kcp"; break;
+        default:  fprintf(stderr, "Unsupported protocol '%c'\n", protocol); exit(1);
         }
+        ++index;
     }
     const char* host = argv[index++];
     int port = atoi(argv[index++]);
@@ -195,34 +195,39 @@ Examples: nc 127.0.0.1 80\n\
     }
 
     // socket
-    if (protocol == 1) {
-#if TEST_SSL
-        // ssl
-        sockio = hloop_create_ssl_client(loop, host, port, on_connect, on_close);
-#else
+    if (protocol == 't' || protocol == 's') {
         // tcp
         sockio = hloop_create_tcp_client(loop, host, port, on_connect, on_close);
-#endif
+        if (sockio == NULL) {
+            return -20;
+        }
+        if (protocol == 's') {
+            if (strcmp(hssl_backend(), "nossl") == 0) {
+                fprintf(stderr, "Please recompile WITH_SSL!\n");
+                exit(1);
+            }
+            hio_enable_ssl(sockio);
+        }
     }
-    else if (protocol == 2) {
+    else if (protocol == 'u' || protocol == 'k') {
         // udp
         sockio = hloop_create_udp_client(loop, host, port);
-#if TEST_KCP
-        static kcp_setting_t s_kcp_setting;
-        memset(&s_kcp_setting, 0, sizeof(kcp_setting_t));
-        s_kcp_setting.conv = 123456;
-        // fast mode
-        s_kcp_setting.nodelay = 1;
-        s_kcp_setting.interval = 10;
-        s_kcp_setting.fastresend = 2;
-        s_kcp_setting.nocwnd = 1;
-        hio_set_kcp(sockio, &s_kcp_setting);
+        if (sockio == NULL) {
+            return -20;
+        }
+        if (protocol == 'k') {
+#if WITH_KCP
+            static kcp_setting_t s_kcp_setting;
+            kcp_setting_init_with_normal_mode(&s_kcp_setting);
+            s_kcp_setting.conv = hv_rand(1, 999999);
+            hio_set_kcp(sockio, &s_kcp_setting);
+#else
+            fprintf(stderr, "Please recompile WITH_KCP!\n");
+            exit(1);
 #endif
+        }
         hio_read(sockio);
     }
-    if (sockio == NULL) {
-        return -20;
-    }
     // printf("sockfd=%d\n", hio_fd(sockio));
     hio_setcb_close(sockio, on_close);
     hio_setcb_read(sockio, on_recv);