C语言socket send()数据缓存问题
来源:互联网 发布:工业怪兽 知乎 编辑:程序博客网 时间:2024/05/17 03:02
send()函数默认情况下会使用Nagle算法,Nagle算法通过将未确认的数据存入缓冲区直到积攒到一定数量一起发送的方法,来减少主机发送零碎小数据包的数目。所以如果send()函数发送数据过快的话,该算法会将一些数据打包后统一发出去。如果不了接这种情况,接收端采会遇到看似很奇怪的问题,比如成功recv()的次数与成功send()的次数不相等,在这中情况下,接收端可以通过recv()的返回值是否为0来判断发送端是否发送完毕。
通过setsockopt()的TCP_NODELAY选项来禁用Nagle算法。但经试验这种方法似乎不总是有效,不过对于相同数量的send(),设置了TCP_NODELAY选项后recv()成功的次数要比设置之前多出几倍。这是不是说明设置了TCP_NODELAY后,系统会进最大的努力不去缓存,但是如果send的实在太快的话,还是会缓存的。
因此,如果你不希望send()的数据被本地缓存到一定数量之后再发送,而是send()多少次就发送多少次,稳妥的方式还是每次send之后调用一下usleep()函数,给系统一个反应的时间。
下面的例子演示了send()调用的快慢对数据是否打包的影响,注释掉server里的usleep(1000),会导致数据打包发送。
TCP_NODELAY是唯一使用IPPROTO_TCP层的选项,宏TCP_NODELAY的头文件是linux/tcp.h或者netinet/tcp.h。
因为不知到send()数据缓存的问题,我调试一天的程序,我的五一劳动节啊!!
server.c:
#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/wait.h>#include<netinet/in.h>#include<netdb.h>#include<arpa/inet.h>#include<netinet/tcp.h>//#include<linux/tcp.h>int main(){int socksv, sockcl;struct sockaddr_in server_addr;struct sockaddr_in client_addr;int sin_size;if((socksv = socket(AF_INET, SOCK_STREAM, 0)) == -1){printf("sever socket fail\n");return -1;}memset(&server_addr, 0, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(6001);server_addr.sin_addr.s_addr = INADDR_ANY;int r = 1;setsockopt(socksv, SOL_SOCKET, SO_REUSEADDR, &r, sizeof(int));int t = 1;if(-1 == setsockopt(socksv, IPPROTO_TCP, TCP_NODELAY, &t, sizeof(int))){printf("setsockopt fail\n");return -1;}if(bind(socksv, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1){printf("server bind fail\n");return -1;}if(listen(socksv, 5) == -1){printf("server listen fail\n");return -1;}while(1){sin_size = sizeof(struct sockaddr_in);if((sockcl = accept(socksv, (struct sockaddr *)&client_addr, &sin_size)) == -1){printf("server accept fail\n");continue;}int times = 1024;int allbytes = 0;int i;for(i = 0; i < times; i++){char buf[] = "#this is a message from ptypeServer";int sendbytes;if((sendbytes = send(sockcl, buf, strlen(buf), 0)) == -1){printf("server send fail\n");}usleep(1000);allbytes += sendbytes;}printf("have send %d packages to client, allbytes=%d\n", times, allbytes);close(sockcl);}}
client.c :
#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/wait.h>#include<netinet/in.h>#include<netdb.h>#include<arpa/inet.h>int main(){int socksv;char buf[1024 * 1024];if((socksv = socket(AF_INET, SOCK_STREAM, 0)) == -1){printf("socket fail\n");return -1;}struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(6001);server_addr.sin_addr.s_addr = inet_addr("192.168.1.100");if(connect(socksv, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){printf("connect fail\n");return -1;}int times = 0;int allbytes = 0;int numbytes = 1;while(numbytes != 0){times++;if((numbytes = recv(socksv, buf, sizeof(buf), 0)) == -1){printf("recv fail\n");return -1;}//buf[numbytes] = '\0';//printf("numbytes=%d buf=[%s]\n", numbytes, buf);allbytes += numbytes;}printf("server is closed, have recv %d packages from server, ""allbytes=%d\n", times - 1, allbytes);}
参阅:http://baike.baidu.com/link?url=-QgA0U7iv5tno-qnorYKDMNazOeOdcGk-pKIVFcOy-n6vhoITKdzlCg1VZYjqJ1DnOlpaaA54E7HrqQX6Bc_e_
2 0
- C语言socket send()数据缓存问题
- Send File In C Socket
- Send File In C Socket
- 【C语言】缓存区问题
- C# Socket的Send问题
- LINUX C语言 SOCKET 服务器断开导致客户端SEND崩溃问题解决办法
- linux C语言 SOCKET 服务器断开导致客户端SEND崩溃问题解决办法
- C语言简单数据缓存实现
- send(经socket传送数据)
- windows socket编程中send与recv函数的收发数据不一致问题
- socket在发送一段时间数据后send卡死问题的解决
- Linux c socket TCP_NODELAY fast send
- c++socket通信的recv和send
- 【c语言】清空缓存 的问题
- 【c语言】清空缓存 的问题
- Socket的Send,Recv的长度问题
- Socket 的 Send Recv 的长度问题
- Socket的Send,Recv的长度问题
- ListView的优化
- MVP -----个人理解与示例(android例子 实现)
- jquery 使用
- Zxing图片识别 从相册选二维码图片解析总结
- Java的常见出错和java JDK的配置
- C语言socket send()数据缓存问题
- Cocos2d-x 2.0 按键加速处理深入分析
- SSH和SMB的使用
- iOS开发 -- 分析CrashLog (3) Hopper逆向分析
- C#——抽象类和接口
- js中apply的用法(转)
- JAX-WS - 通过xjc命令把Schema生成Java
- hdu Tian Ji -- The Horse Racing
- server Library [Apache Tomcat v6.0](unbound)