当前位置:  技术问答>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,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要求多少,并发量多少也决定成功率,最关键你还是要看分析自己的代码,我在这瞎说也没啥意思

|
也可能是你的监听处理有问题,可以snoop或tcpdump抓包分析下TCP报文。

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Linux下read函数默认到底是阻塞的还是非阻塞的?
  • 如何从阻塞式的read中取得阻塞了多少时间?
  • Select() 是否只能在非阻塞IO里使用,在阻塞IO里可以使用吗?
  • 请教sleep和pthread_delay_np:阻塞线程/阻塞进程?
  • recvfrom函数,已经设置好非阻塞模式,是否还存在阻塞的风险?
  • 怎么解除recvfrom阻塞的阻塞状态
  • linux 如何用SOCKET设置函数设置阻塞和非阻塞?
  • 非阻塞SOCKET,竟然也会阻塞?
  • 请教:线程中调用一个阻塞的方法后,进程及其它线程会阻塞么?
  • linux C socke编程 创建的socket默认是阻塞的还是非阻塞的?
  • 论坛 iis7站长之家
  • 什么是非阻塞啊?我用下面的程序设计的,用非阻塞和不用都一样啊?
  • 初级问题,socket(AF_INET, SOCK_STREAM, 0)是阻塞式还是非阻塞式?
  • 请问:我发现在linux上的网络编程时, 若客户端连不上服务端,就会阻塞,但如果是在UNIX上,若连不上,会马上返回,并不阻 塞,怎样让它也能阻塞啊?
  • 关于《Unix网络编程》在ubuntu 8.04下运行的问题,服务器端阻塞在accept调用,客户端阻塞在connect调用,导致连接失败
  • 关于socket编程中阻塞的问题
  • linux fwrite 阻塞问题
  • 关于非阻塞I/O
  • 如何判断一个线程是否处于阻塞状态
  • 关于fread是否会阻塞的问题


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3