linux 简易 socket 客户端调试程序
编译:gcc main.c -lpthread
以换行符(\n)分包运行:./a.out 127.0.0.1 8080
以两字节表示包大小(大端字节序)分包运行:./a.out 127.0.0.1 8080 1
运行时发送的数据与接收的数据分别以十六进制和字符串形式输出
此代码为简单调试使用,可根据需求修改打包/解包模式
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdint.h> 4 #include <string.h> 5 #include <pthread.h> 6 #include <unistd.h> 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <netinet/in.h> 10 #include <arpa/inet.h> 11 #include <sys/types.h> 12 #include <sys/socket.h> 13 14 #define CACHE_SIZE 2048 15 16 int is_little() 17 { 18 unsigned int tmp = 1; 19 return *(char*)&tmp; 20 } 21 22 23 unsigned short swap2(unsigned short value) 24 { 25 if(!is_little()) return value; 26 return ( (value & 0xFF) << 8)|( (value & 0xFF00)>>8); 27 } 28 29 void log_hex(char* tag, char* buf, int sz) 30 { 31 fprintf(stderr, "%s:\n\t", tag); 32 for(int i = 0; i < sz; i++) 33 fprintf(stderr, "%02X ", buf[i]); 34 fprintf(stderr, "\n"); 35 } 36 37 static int client_fd = -1; 38 static int is_pack = 0; 39 static void* thread_recv(void* p){ 40 char queue[CACHE_SIZE*2] = {0}; 41 int head = 0; 42 int len = 0; 43 while(1){ 44 if(client_fd < 0 ) break; 45 usleep(500); 46 47 char tmp[CACHE_SIZE]={0}; 48 int r = recv(client_fd, tmp, CACHE_SIZE,0); 49 50 if(r == 0) 51 continue; 52 if(r < 0 &&( errno == EAGAIN || errno == EINTR) ) 53 continue; 54 if(r > 0){ 55 memcpy(&queue[head + len], tmp, r); 56 len += r; 57 } 58 fprintf(stderr, "RECV COUNT %d",r); 59 log_hex("", tmp, r); 60 if(is_pack){ 61 while(len > 2){ 62 short size = 0; 63 memcpy(&size, &queue[head], 2); 64 size = swap2(size); 65 if(len < (size + 2) ) break; 66 67 memcpy(tmp, &queue[head + 2], size); 68 if(len > (size + 2)){ 69 memcpy(&queue, &queue[head + size + 2], len - size - 2); 70 len -= size + 2; 71 }else { 72 len = 0; 73 } 74 head = 0; 75 tmp[size] = 0; 76 fprintf(stderr, "\t%s\n", tmp); 77 78 }//end of while 79 }else{ 80 queue[len] = 0; 81 fprintf(stderr, "\t%s\n", queue); 82 head = 0; 83 len = 0; 84 }// end of if is_pack else 85 } 86 return NULL; 87 } 88 89 int main(int argc, char* argv[]) 90 { 91 if(argc < 3){ 92 fprintf(stderr, "parms not enough\n"); 93 return 0; 94 } 95 is_pack = 0; 96 if(argc > 3) is_pack = 1; 97 98 client_fd = socket(AF_INET, SOCK_STREAM,0); 99 struct sockaddr_in addr; 100 addr.sin_addr.s_addr = inet_addr(argv[1]); 101 addr.sin_family = AF_INET; 102 addr.sin_port=htons(atoi(argv[2])); 103 int r = connect(client_fd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)); 104 if( r == -1){ 105 fprintf(stderr, "Connedt failed\n"); 106 return 0; 107 } 108 r = fcntl(client_fd, F_GETFL,0); 109 fcntl(client_fd, F_SETFL, r | O_NONBLOCK); 110 111 pthread_t tid; 112 pthread_create(&tid, NULL, thread_recv, NULL); 113 114 while(!feof(stdin)){ 115 fflush(stdin); 116 char tmp[1024]={0}; 117 char buf[1026]={0}; 118 if(fgets(tmp, sizeof(tmp), stdin) == NULL) 119 break; 120 121 int n = strlen(tmp); 122 memcpy(buf, tmp, n); 123 if(is_pack){ 124 short int pack = n - 1; 125 short int sz = swap2(pack); 126 memcpy(buf, &sz, 2); 127 memcpy(&buf[2], tmp, pack); 128 n = pack + 2; 129 } 130 fprintf(stderr, "SEND COUNT %d",n); 131 log_hex("", buf, n); 132 tmp[n] = 0; 133 fprintf(stderr, "\t%s\n", tmp); 134 135 int k = 0; 136 while(n > 0){ 137 int s = send(client_fd, &buf[k], n,0); 138 if(s < 0 && ( errno == EAGAIN || errno == EINTR) ) 139 continue; 140 k += s; 141 n -= s; 142 } 143 144 if(strcmp(tmp, "quit\n") == 0) 145 break; 146 147 usleep(1000); 148 } 149 150 if(client_fd > -1) 151 shutdown(client_fd,SHUT_RDWR); 152 close(client_fd); 153 client_fd = -1; 154 void* status; 155 pthread_join(tid, &status); 156 return 0; 157 }