当前位置: 技术问答>linux和unix
非阻塞socket发送返回的size小于要发送的大小的问题
来源: 互联网 发布时间:2017-01-21
本文导语: 代码在公司电脑上(带不出来,555)明天再贴,先讲下思路: 1、首先socket肯定设置为非阻塞模式 2、write时如果reture 0但是小于要发送的size,则把没有发完的数据保存到重发list中去 4、如果后续发送数据时发现重发l...
代码在公司电脑上(带不出来,555)明天再贴,先讲下思路:
1、首先socket肯定设置为非阻塞模式
2、write时如果reture 0但是小于要发送的size,则把没有发完的数据保存到重发list中去
4、如果后续发送数据时发现重发list不为空,说明前面数据没发完,为了不乱序也加到重发list中去;否则执行上面的2和3判断流程。
5、select监听到可写时间后遍历发送重发队列中的数据,如果全部发送完则清楚可写事件监听;否则继续监听
6、write返回0,说明socket断开,释放资源。
我实际测试的情况是,压力测试时,一个循环发送几百包数据,一切正常。如果把发送数据包改为1024以上则将出现只能成功发出去几包,剩余包全部保存在重发队列中,但是可写事件一直米有监听到。
个人感觉上面的逻辑没有问题,实在不知从何开始下手了
1、首先socket肯定设置为非阻塞模式
2、write时如果reture 0但是小于要发送的size,则把没有发完的数据保存到重发list中去
4、如果后续发送数据时发现重发list不为空,说明前面数据没发完,为了不乱序也加到重发list中去;否则执行上面的2和3判断流程。
5、select监听到可写时间后遍历发送重发队列中的数据,如果全部发送完则清楚可写事件监听;否则继续监听
6、write返回0,说明socket断开,释放资源。
我实际测试的情况是,压力测试时,一个循环发送几百包数据,一切正常。如果把发送数据包改为1024以上则将出现只能成功发出去几包,剩余包全部保存在重发队列中,但是可写事件一直米有监听到。
个人感觉上面的逻辑没有问题,实在不知从何开始下手了
|
1,ioctl FIONREAD 可以查询读缓冲区, 不知道写缓冲区怎么查, 挂了就挂了呗, 客户端自己有数就行了, 下次客户端再次连接服务器,根据自己已收到的数据量请求断点续传就可以了.
2,SO_LINGER分两种,一种是阻塞等一段时间,只有所有数据都发送出去并被确认才返回或者超时返回,很明显这个不应该出现的服务器里,服务器没时间给你阻塞.
另一种是直接送TCP RST给对方, 对方收到RST会立即关闭连接. 这种情况是为了防止服务端的监听端口被大量的TIME_WAIT占用,当然这根本不是问题,设置了SO_REUSEADDR之后服务器的accpet不会在乎这些. 我也没去研究web服务器为什么要使用这个SO_LINGER选项, 不过的确看到过相关代码, 我再去读读吧.
给你截了一段, 如下所示:
owenliang@linux-7lsl:/usr/local/sbin> netstat -tanlp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:2048 0.0.0.0:* LISTEN 8870/lighttpd
tcp 0 52 172.17.66.58:22 172.17.66.57:1566 ESTABLISHED -
tcp 0 0 :::111 :::* LISTEN -
tcp 0 0 :::22 :::* LISTEN -
tcp 0 0 ::1:631 :::* LISTEN -
tcp 0 0 ::1:25 :::* LISTEN -
owenliang@linux-7lsl:/usr/local/sbin> netcat 127.0.0.1 2048
hellpo
owenliang@linux-7lsl:/usr/local/sbin> netstat -tanlp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:2048 0.0.0.0:* LISTEN 8870/lighttpd
tcp 0 52 172.17.66.58:22 172.17.66.57:1566 ESTABLISHED -
tcp 0 0 127.0.0.1:41940 127.0.0.1:2048 TIME_WAIT -
tcp 0 0 :::111 :::* LISTEN -
tcp 0 0 :::22 :::* LISTEN -
tcp 0 0 ::1:631 :::* LISTEN -
tcp 0 0 ::1:25 :::* LISTEN -
|
还没看你代码,红色部分不需要,你这个设计是很主流的,I/O复用程序都是这么一个框架.
|
===送数据包改为1024以上则将出现只能成功发出去几包
注意一些报文或者buffer定义的大小,有时候定义小了,发送时clicent端会自动断掉(我说的是发往企业级esb)
数据包增大后压力测试的tps是不是有明显的下降,首先是因为非阻塞模式不容你有一点的wait,数据量一大导致发包率下降也是说的痛的,具体你压力测试的tps要求多少,并发量多少也决定成功率,最关键你还是要看分析自己的代码,我在这瞎说也没啥意思
注意一些报文或者buffer定义的大小,有时候定义小了,发送时clicent端会自动断掉(我说的是发往企业级esb)
数据包增大后压力测试的tps是不是有明显的下降,首先是因为非阻塞模式不容你有一点的wait,数据量一大导致发包率下降也是说的痛的,具体你压力测试的tps要求多少,并发量多少也决定成功率,最关键你还是要看分析自己的代码,我在这瞎说也没啥意思
|
也可能是你的监听处理有问题,可以snoop或tcpdump抓包分析下TCP报文。