http://blog.chinaunix.net/uid-8489474-id-2031025.html

tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据.

在阻塞模式下, send函数的过程是将应用程序请求发送的数据拷贝到发送缓存中发送就返回.但由于发送缓存的存在,表现为:如果发送缓存大小比请求发送的大小要大,那么send函数立即返回,同时向网络中发送数据;否则,send会等待接收端对之前发送数据的确认,以便腾出缓存空间容纳新的待发送数据,再返回(接收端协议栈只要将数据收到接收缓存中,就会确认,并不一定要等待应用程序调用recv),如果一直没有空间能容纳待发送的数据,则一直阻塞;

在非阻塞模式下,send函数的过程仅仅是将数据拷贝到协议栈的缓存区而已,如果缓存区可用空间不够,则尽能力的拷贝,立即返回成功拷贝的大小;如缓存区可用空间为0,则返回-1,同时设置errno为EAGAIN.

需要注意的是,虽然将发送缓存设置成了10k,但实际上,协议栈会将其扩大1倍,设为20k.

应用程序表现如下:

在实际应用中,如果发送端是非阻塞发送,由于网络的阻塞或者接收端处理过慢,通常出现的情况是,发送应用程序看起来发送了10k的数据,但是只发送了2k到 对端缓存中,还有8k在本机缓存中(未发送或者未得到接收端的确认).那么此时,接收应用程序能够收到的数据为2k.假如接收应用程序调用recv函数获 取了1k的数据在处理,在这个瞬间,发生了以下情况之一,双方表现为:

A. 发送应用程序认为send完了10k数据,关闭了socket:
发送主机作为tcp的主动关闭者,连接将处于FIN_WAIT1的半关闭状态(等待对方的ack),并且,发送缓存中的8k数据并不清除,依然会发送给对 端.如果接收应用程序依然在recv,那么它会收到余下的8k数据(这个前题是,接收端会在发送端FIN_WAIT1状态超时前收到余下的8k数据.), 然后得到一个对端socket被关闭的消息(recv返回0).这时,应该进行关闭.

B. 发送应用程序再次调用send发送8k的数据:
假如发送缓存的空间为20k,那么发送缓存可用空间为20-8=12k,大于请求发送的8k,所以send函数将数据做拷贝后,并立即返回8192;

假如发送缓存的空间为12k,那么此时发送缓存可用空间还有12-8=4k,send()会返回4096,应用程序发现返回的值小于请求发送的大小值后,可以认 为缓存区已满,这时必须阻塞(或通过select等待下一次socket可写的信号),如果应用程序不理会,立即再次调用send,那么会得到-1的值, 在linux下表现为errno=EAGAIN.

C. 接收应用程序在处理完1k数据后,关闭了socket:
接收主机作为主动关闭者,连接将处于FIN_WAIT1的半关闭状态(等待对方的ack).然后,发送应用程序会收到socket可读的信号(通常是 select调用返回socket可读),但在读取时会发现recv函数返回0,这时应该调用close函数来关闭socket(发送给对方ack);

如果应用程序通过select()函数仅检测该socket句柄是否可写,它会返回应用层可写.
假设发送应用程序收到可读或可写的信号后,继

TCP send 阻塞与非阻塞相关推荐

  1. recv send 阻塞和非阻塞

    int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据 ...

  2. socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)

    socket的阻塞模式和非阻塞模式 无论是Windows还是Linux,默认创建socket都是阻塞模式的 在Linux中,可以再创建socket是直接将它设置为非阻塞模式 int socket (i ...

  3. tcp 阻塞与非阻塞

    原文地址:http://blog.chinaunix.net/uid-8489474-id-2031025.html tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻 ...

  4. Linux Socket网络编程UDP、TCP 阻塞与非阻塞 断线重连机制

    三种非阻塞模式的方法: (1) fcntl函数 int Mode = fcntl(sockfd, F_GETFL, 0);       //获取文件的Mode值     fcntl(sockfd, F ...

  5. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值

    recv: 阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小, 特别:非阻塞模式下返回 值 <0时并且(errno == EINTR || e ...

  6. recv 和 send 阻塞和非阻塞的区别

    目录 答案 深入说明 在 epoll 中的应用 总结 拓展 答案 阻塞,事情干不完就不要回来了! 非阻塞,能干多少就是多少,赶紧回来! 深入说明 // 将内核接收缓冲区中的数据 copy 到应用层中用 ...

  7. linux下recv 、send阻塞、非阻塞区别和用法

    非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明:        基本概念: 阻塞IO:: socket 的阻塞模 ...

  8. python gevent模块 下载_Python协程阻塞IO非阻塞IO同步IO异步IO

    Python-协程-阻塞IO-非阻塞IO-同步IO-异步IO 一.协程 协程又称为微线程 CPU 是无法识别协程的,只能识别是线程,协程是由开发人员自己控制的.协程可以在单线程下实现并发的效果(实际计 ...

  9. IO之阻塞与非阻塞比较

    在网络程序中遇到的一些问题进行了总结, 这里主要针对的是我们常用的TCP socket相关的总结, 可能会存在错误, 有任何问题欢迎大家提出. 对于网络编程的更多详细说明建议参考下面的书籍 <U ...

最新文章

  1. 使用相对路径时,./、../、../../,代表的什么?
  2. R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(设置异常值的形状、颜色)实战
  3. python中的对象拷贝
  4. Kali Day01 --- arpspoof命令进行断网攻击(ARP欺骗)
  5. Learning hard C#学习笔记 孤军深入
  6. QT绘制散点图(1)
  7. import openfire4.0.2 source code in eclipse
  8. 【渝粤题库】陕西师范大学210022 学前儿童语言教育 作业(专升本)
  9. C++自定义异常处理
  10. python ui自动_pytest+python下的UI自动化基础框架
  11. 上位机与西门子PLC通信协议
  12. 少儿编程家长疑问解答
  13. 图像质量评价数据库与常见评价算法总结
  14. Matlab线性拟合和非线性拟合
  15. android卡通头像,Face V(卡通头像制作)
  16. 2022年武汉经开区首次进入规模以上工业企业奖励资金申报条件时间及资料
  17. 排序算法之插入排序法
  18. grpc AS编译报No such property: javaCompilerTask for class错误
  19. ssm项目笔记(五)图片存储方案
  20. java 类型转换 效率_盘点16个有用的Java工具类,显著提升工作效率!

热门文章

  1. C++服务器设计(七):聊天系统服务端实现
  2. 【转】phpize学习
  3. C++细节系列(零):零散记录
  4. JSON学习资料整理
  5. android运行时状态,Android 如何保存Android 运行时状态
  6. 程序控制发送文件到邮箱_Kindle电子邮箱推送
  7. js转json工具_菜鸟丨Egert3D微信小游戏发布与Unity工具使用
  8. matlab命令 脑电波,基于Matlab的脑电波信号处理
  9. matlab多项式加法运算,matlab多项式运算与代数方程求解解析.ppt
  10. C学习杂记(四)sizeof计算联合体大小