C语言socket send()数据缓存问题
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);
}
C语言socket send()数据缓存问题的更多相关文章
- 云计算之路-阿里云上:原来“黑色0.1秒”发生在socket读取数据时
在昨天的博文(云计算之路-阿里云上:读取缓存时的“黑色0.1秒”)中我们犯了一个很低级的错误——把13ms算成了130ms(感谢陈硕发现这个错误!),从而对问题的原因作出了错误的推断,望大家谅解! 从 ...
- 文件缓存tmpfs + 数据缓存SSDB(一)
一.文件缓存tmpfs 1.特性 1) 基于内存的文件系统,RAW+SWAP,虚拟内存 2) tmpfs使用虚拟内存,/dev/shm/使用共享内存 3) 访问速度快,可以动态调整大小 4) 没有持久 ...
- jQuery 2.0.3 源码分析 数据缓存
历史背景: jQuery从1.2.3版本引入数据缓存系统,主要的原因就是早期的事件系统 Dean Edwards 的 ddEvent.js代码 带来的问题: 没有一个系统的缓存机制,它把事件的回调都放 ...
- Memcached 数据缓存系统
Memcached 数据缓存系统 常用命令及使用:http://www.cnblogs.com/wayne173/p/5652034.html Memcached是一个自由开源的,高性能,分布式内存对 ...
- memcached基于socket访问memcache缓存服务器
memcached基于socket访问memcache缓存服务器 操作memcache常用三种方法: .memcache基于php_memcache.dll扩展(php扩展) .memcached基于 ...
- 第十七课:js数据缓存系统的原理
这一章主要讲的是jQuery的缓存系统的历史发展,以及他自己的框架的缓存系统的实现.都是源码解析. 我就挑几个重点讲下: (1)jQuery的缓存机制的原理 jQuery的缓存机制实现的原理是在元素中 ...
- C语言socket编程
建议先去看一下思路 真的写的很不错呦~ 思路参考博客:https://www.cnblogs.com/renfanzi/p/5713054.html linux c语言socket编程代码(单一服务端 ...
- C# Socket 接受数据不全的处理
由于Socket 一次传输数据有限,因此需要多次接受数据传输. 解决办法一: int numberOfBytesRead = 0; int totalNumberOfBytes = 0 ...
- 基于IBM Bluemix的数据缓存应用实例
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:IBM® Data Cache for Bluemix 是快速缓存服务.支持 Web 和 ...
随机推荐
- 【MVC 1】MVC+EF实体框架—原理解析
导读:在之前,我们学过了三层框架,即:UI.BLL.DAL.我们将页面显示.逻辑处理和数据访问进行分层,避免了一层.两层的混乱.而后,我们又在经典三层的基础上,应用设计模式:外观.抽象工厂+反射,使得 ...
- SQL 优化案例之变更表结构
从慢日志报表中看到一条很长的SQL select id from myinfo and (( SUBSTRING_INDEX(location_axis, ) ) ) ), '$%') ) or ( ...
- CentOS 7.0如何安装配置iptables和seLinux以及firewalld
一.配置防火墙,开启80端口.3306端口 CentOS .0默认使用的是firewall作为防火墙,这里改为iptables防火墙. .关闭firewall: systemctl stop fire ...
- HDU——3786找出直系亲属(DFS+回溯)
找出直系亲属 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- PAT天梯赛练习题——L3-005. 垃圾箱分布(暴力SPFA)
L3-005. 垃圾箱分布 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁 ...
- 刷题总结——书架(bzoj1861)
题解: Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然 ...
- 查看Linux每个进程的流量和带宽
原文:https://blog.csdn.net/monkeynote/article/details/45867803 作为一个系统管理员,有时候需要搞清楚一台机器上的哪个进程占用了较高的网络带宽. ...
- UVa10214 Trees in a Wood.
先算第一象限能看到的树,答案乘以4就是四个象限的数的总数,再加上坐标轴上四棵树,就是总共能看到的树. 树的总数为(2*a+1)*(2*b+1)-1 ←矩形面积除去原点位置 设一棵树的坐标是(x,y) ...
- Tarjan 算法 自学整理
算法介绍 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量( ...
- 使用EventNext实现基于事件驱动的业务处理
事件驱动模型相信对大家来说并不陌生,因为这是一套非常高效的逻辑处理模型,通过事件来驱动接下来需要完成的工作,而不像传统同步模型等待任务完成后再继续!虽然事件驱动有着这样的好处,但在传统设计上基于消息回 ...