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 和 ...
随机推荐
- 【Luogu】P1119灾后重建(Floyd)
题目链接 见题解: feilongz. 这里只放代码. #include<cstdio> #include<cstring> #include<cstdlib> # ...
- noip2018——题解&总结
近期正在疯狂复习某些东西,这篇博客尽量年底更完……(Day2T2除外) 好了,所有的希望都破灭了,原来这就是出题人的素质.——一个被欺骗的可怜 $OIer$ 人生中倒数第三次 $noip$ (Mayb ...
- oracle查询正在执行的语句以及正被锁的对象
--查询Oracle正在执行的sql语句及执行该语句的用户 b.username 登录Oracle用户名, b.serial#, spid 操作系统ID, paddr, ...
- day1之校花网小试牛刀
一 利用生成器来完成爬去校花网视频 import requests import re import os import hashlib import time DOWLOAD_PATH=r'D:\D ...
- 【Tyvj1982】武器分配(费用流)
题意:有N个人要从A个物品中各取一个,B个物品中各取一个,选取第i个A类物品和第j个B类物品的费用是(a[i]-b[j])^2 求最小总花费 n<=a,b<=80 a[i],b[i]< ...
- UOJ#370. 【UR #17】滑稽树上滑稽果
$n \leq 1e5$个点,每个点有个权值$a_i \leq 2e5$.现将点连成树,每个点$i$的链接代价为$a_i \ \ and \ \ i父亲的代价$,这里的$and$是二进制按位与,求最小 ...
- R语言入门-画图(二)--heatmap
一.函数参数: pheatmap参数: treeheight_row #横有多长 treeheight_col #竖有多长 cluster_cols=FLASE #单一方向聚类,也就是只有一边有树状结 ...
- js-判断当前页面是否在微信浏览器中打开
方案一:推荐 var ua = navigator.userAgent.toLowerCase(); var isWinxin = ua.indexOf('micromessenger') != -1 ...
- Oracle 实现 一个关键字 匹配多个 字段
有这么一个需求,满足只有一个输入框的条件下,支持不同数据列的搜索结果. 说白了,就是这个 输入框 既可以用来 搜索姓名,也可以搜索 年龄,地址等. 分析: 一般情况下,我们的一个输入框对应 数据库 ...
- T1008 选数 codevs
http://codevs.cn/problem/1008/ 题目描述 Description 已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整 ...