鉴于TCP之简单回传(一) 中所出现的问题,本博文所要采取的一种方法是:
客户端:先向服务器传送一个 int32_t 大小的数据,表示随后所要发送数据的真实长度; 服务器:先接收一个int32_t 大小的数据,再接收真实的数据;
本程序中所用到的函数都可以在 TCP之函数封装 中找到;
server服务器端具体实现:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) void do_server(int fd); int main(int argc, const char *argv[]) { //socket int listenfd = socket(AF_INET, SOCK_STREAM, 0 ); if( -1 == listenfd) ERR_EXIT("socket"); //地址复用 int on = 1; if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on) < 0) ERR_EXIT("setsockopt"); //bind struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(8888); //主机字节序转化为网络字节序 addr.sin_addr.s_addr = inet_addr("127.0.0.1");//点分十进制转化成网络字节序 if( -1 == bind( listenfd, (struct sockaddr*)&addr, sizeof(addr))) ERR_EXIT("bind"); //listen if( -1 == listen(listenfd,SOMAXCONN )) ERR_EXIT("listen"); //accept int peerfd = accept(listenfd, NULL, NULL);//对方的IP&PORT //read&write do_server(peerfd); //close close(peerfd); close(listenfd); return 0; } void do_server(int fd) { char recvbuf[1024100] = {0}; int cnt =0; while(1) { int32_t len = recv_int32(fd);//先接收一个表示真是长度的int型数据 int nread = readn(fd, recvbuf, len);//读取数据 if(nread == -1)//err { if(errno == EINTR) continue; ERR_EXIT("read"); }else if (nread == 0 || nread < len )//write close { printf("close...\n"); exit(EXIT_FAILURE); } // ok printf("count = %d recv size = %d\n",++cnt, nread); memset(recvbuf, 0, sizeof(recvbuf)); } }
client客户端具体实现:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) void do_server(int fd); int main(int argc, const char *argv[]) { //socket int peerfd = socket(AF_INET, SOCK_STREAM,0); if( -1 == peerfd) ERR_EXIT("socket"); //connect struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(8888); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); if( -1 == connect(peerfd,(struct sockaddr*)&addr, sizeof(addr) )) ERR_EXIT("connect"); //read&write do_server(peerfd); return 0; } void do_server(int fd) { #define SIZE 1024 char sendbuf[SIZE +1]= {0}; int i ; for (i = 0; i < SIZE; i++) { sendbuf[i]= ‘a‘; } int cnt =0; while(1) { int i; for (i = 0; i < 10; i++) { send_int32(fd, SIZE);//先发送一个表示真实长度的int型数据 int nwrite =writen(fd, sendbuf, SIZE);//写数据 if( nwrite != SIZE)//err ERR_EXIT("writen"); printf("cout = %d,write %d bytes\n",++cnt, SIZE); } nano_sleep(4.5); } }
测试结果:
./server count = 1 recv size = 1024 count = 2 recv size = 1024 count = 3 recv size = 1024 count = 4 recv size = 1024 count = 5 recv size = 1024 count = 6 recv size = 1024 count = 7 recv size = 1024 count = 8 recv size = 1024 count = 9 recv size = 1024 count = 10 recv size = 1024 count = 11 recv size = 1024 count = 12 recv size = 1024 count = 13 recv size = 1024 count = 14 recv size = 1024 count = 15 recv size = 1024 count = 16 recv size = 1024 count = 17 recv size = 1024 count = 18 recv size = 1024 count = 19 recv size = 1024 count = 20 recv size = 1024
./client cout = 1,write 1024 bytes cout = 2,write 1024 bytes cout = 3,write 1024 bytes cout = 4,write 1024 bytes cout = 5,write 1024 bytes cout = 6,write 1024 bytes cout = 7,write 1024 bytes cout = 8,write 1024 bytes cout = 9,write 1024 bytes cout = 10,write 1024 bytes cout = 11,write 1024 bytes cout = 12,write 1024 bytes cout = 13,write 1024 bytes cout = 14,write 1024 bytes cout = 15,write 1024 bytes cout = 16,write 1024 bytes cout = 17,write 1024 bytes cout = 18,write 1024 bytes cout = 19,write 1024 bytes cout = 20,write 1024 bytes
时间: 2024-10-12 19:10:47