易截截图软件、单文件、免安装、纯绿色、仅160KB

Linux上TCP丢失小包不可见的解决

Linux上TCP丢失小包不可见的解决
 作者:千里孤行(http://blog.csdn.net/yanghehong)
有网友在做一个Linux上的客户端碰到这样的问题:
我们在Linux下开发一个网络客户端程序(服务器是不可修改的),不断向服务器不定期发送一些很小的包(一般只有几十字节),现在出现这种情况:大部分包正常发送,但是当无线Modem断开的时候,如果这个时候刚好有一个小包,就可能丢失,但在程序中却显示已经发送成功,导致丢包。
我们分析原因是这样:
1:主程序创建Socket,TCP/IP方式,并采用Stream方式
2:主程序调用Write,写入小包到系统的Socket缓冲区,并返回成功写入,由于字节数很小,所以一般都立即返回写入成功!
3:Linux TCP/IP协议栈把Socket缓冲区数据发送到服务器
如果第二步完成,刚好在第三步出现无线Modem断开的情况,就会导致主程序以为已经发送成功了,但服务器收不到的情况。
我们在网络上搜索了大量的资料,但是没有找到最终的解决方案,一般都是要求修改协议,加上对小包的ACK处理,但我们这边无法控制服务器。
我们也试着控制KeepAlive和NoDelay,但还是没效果:
//对sock_cli设置KEEPALIVE和NODELAY
len = sizeof(unsigned int);
setsockopt(sock_cli, SOL_SOCKET, SO_KEEPALIVE, &optval, len);//使用KEEPALIVE
setsockopt(sock_cli, IPPROTO_TCP, TCP_NODELAY, &optval, len);//禁用NAGLE算法
请问有什么方式可以解决这种情况?
如果是Windows的,可以把内核的发送buffer设为0,也就是socket的SO_SNDBUF选项。那么直到服务器TCP收到数据并ack了,客户端的写入才返回成功。
不过这种设SO_SNDBUF的方法在Linux上是行不通的。Linux不让把发送buffer设为0。
Linux内核中的代码是这样的:
Socket.c
 int sock_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
{
case SO_SNDBUF:
/* Don't error on this BSD doesn't and if you think
about it this is right. Otherwise apps have to
play 'guess the biggest size' games. RCVBUF/SNDBUF
are treated in BSD as hints */
if (val > sysctl_wmem_max)
val = sysctl_wmem_max;
set_sndbuf:
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
if ((val * 2) < SOCK_MIN_SNDBUF)
sk->sk_sndbuf = SOCK_MIN_SNDBUF;
else
sk->sk_sndbuf = val


相关文档:

几个linux桌面下常用的软件#archlinux (1)

1、  freemind 思考软件
sudo pacman -S freemind
2、  gnomesword  圣经学习软件# clucene-0.9.21b-1  sword-1.6.1-1  xiphos-3.1.2-1 
sudo pacman -S gnomesword
3、exaile音乐播放器
sudo pacman -S exaile
4、安装 mp3blaster
sudo pacman -S mp3blaster
5 、安装msn软件
sud ......

linux启动logo修改

修改目标:用自定义的ppm图片替代/drivers/video/logo/logo_linux_clut224.ppm
同时删除logo_linux_clut224.c logo_linux_clut224.o文件这样才能使编译的使用logo_linux_clut224.ppm重新编译
ppm图片的生成:
# pngtopnm logo_linux_clut224.png > logo_linux_clut224.pnm
# pnmquant 224 logo_linux_clut224.pnm &g ......

linux 设置环境变量

下面以配置java
环境变量为例介绍三种配置环境变量的方法。
 
1.修改/etc/profile文件
如果你的计算机仅仅作为开发使用时推荐使用这种方法,因为所有用户
的shell
都有权使用这些环境变量,可能
会给系统
带来安全性问题。
 
(1)用文本编辑器打开/etc/profile
 
(2)在profile文件末尾加入:
JA ......

linux开机过程深入理解

Linux开机过程理解
一.           Power on
二.           BIOS加电自检:
1.  检测所有周边硬件
2.  寻找启动的磁盘(cd-rom,floppy,IDE HDD,usb device等)
三.     & ......

linux gcc 编译时头文件和库文件搜索路径

一、头文件
 
gcc 在编译时寻找所需要的头文件 :
 
※搜寻会从-I开始
 
※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
 
※再找内定目录
/usr/include 
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/lib/gcc-lib/i386-l ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号