从缓冲上看阻塞与非阻塞socket在发送接收上的区别
最近在网络上看到一些帖子以及回复,同时又搜索了一些网络上关于阻塞非阻塞区别的描述,发现很多人在描述两者的发送接收时操作返回以及缓冲区处理的区别时有不同程度的误解。所以我想写一篇文章来纠正错误,并作为记录方便查阅,如有转载,注明作者(jwybobo2007)以及出处即可。
首先socket在默认情况下是阻塞状态的(未指异步操作以及其它一些特殊用途下,直接默认为非阻塞),这就使得发送以及接收操作处于阻塞的状态,即调用不会立即返回,而是进入睡眠等待操作完成。下面把讨论点分为发送以及接收。
一.发送选用send(这里特指TCP)以及sendto(这里特指UDP)来描述
首先需要说明的是,不管阻塞还是非阻塞,在发送时都会将数据从应用缓冲区拷贝到内核缓冲区(SO_RCVBUF选项声明,除非缓冲区大小为0)。我在网络上看到某些人说,阻塞就是将数据真正发送给对方,并且阻塞是发生在需要把前面的所有数据全部发送出去,然后再发送本次的,而非阻塞则是拷贝到发送缓冲区。我不得不说,上面的这种说法是错误的。
在阻塞模式下send操作将会等待所有数据均被拷贝到发送缓冲区后才会返回。
如果当前发送缓冲总大小为8192,已经拷贝到缓冲的数据为8000,那剩余的大小为192,现在需要发送2000字节数据,那阻塞发送就会等待缓冲区足够把所有2000字节数据拷贝进去,如第一次拷贝进192字节,当缓冲区成功发送出1808字节后,再把应用缓冲区剩余的1808字节拷贝到内核缓冲,而后send操作返回成功发送字节数。
从上面的过程不难看出,阻塞的send操作返回的发送大小,必然是你参数中的发送长度的大小。
在阻塞模式下的sendto操作不会阻塞。
关于这一点的原因在于:UDP并没有真正的发送缓冲区,它所做的只是将应用缓冲区拷贝给下层协议栈,在此过程中加上UDP头,IP头,所以实际不存在阻塞。
在非阻塞模式下send操作调用会立即返回。
关于立即返回大家都不会有异议。还是拿阻塞send的那个例子来看,当缓冲区只有192字节,但是却需要发送2000字节时,此时调用立即返回,并得到返回值为192。从中可以看到,非阻塞send仅仅是尽自己的能力向缓冲区拷贝尽可能多的数据,因此在非阻塞下send才有可能返回比你参数中的发送长度小的值。
如果缓冲区没有任何空间时呢?这时肯定也是立即返回,但是你会得到WSAEWOULDBLOCK/E WOULDBLOCK 的错误,此时表示你无法拷贝任何数据到缓冲区,你最好休息一下再尝试发送。
在非阻塞模式下sendto操作 不会阻塞(与阻塞一致,不作说明)。
二.接收选用recv(这里特指TCP)以及recvfrom(这里特指UDP)来描述
在阻塞模式下recv,recvfrom操作将会阻塞 到缓冲区里有至少一个字节(TCP)或者一个完整UDP数据报才返回。
在没有数据到来时,对它们的调用都将处于睡眠状态,不会返回。
在非阻塞模式下recv,recvfrom操作将会立即返回。
如果缓冲区 有任何一个字节数据(TCP)或者一个完整UDP数据报,它们将会返回接收到的数据大小。而如果没有任何数据则返回错误 WSAEWOULDBLOCK/E WOULDBLOCK。
以上是关于阻塞非阻塞发送接收的区别以及在缓冲区处理上的差别,希望给看到这篇文章的人一些帮助。同时也想纠正网络上的某些错误观点,文章中表述如有错误,望大家指正,谢谢。
from:http://blog.csdn.net/jwybobo2007/archive/2011/01/26/6164362.aspx
从缓冲上看阻塞与非阻塞socket在发送接收上的区别的更多相关文章
- 从缓冲上看阻塞与非阻塞socket在发送接收上的区别(转载)
转自:http://blog.chinaunix.net/uid-24517549-id-4044877.html 首先socket在默认情况下是阻塞状态的,这就使得发送以及接收操作处于阻塞的状态 ...
- 从linux源码看socket的阻塞和非阻塞
从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 大部分高性能网络框架采用的是非阻塞模式.笔者这次就从linux ...
- socket阻塞与非阻塞,同步与异步、I/O模型,select与poll、epoll比较
1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步: 所谓同步,就 ...
- socket阻塞与非阻塞,同步与异步
socket阻塞与非阻塞,同步与异步 作者:huangguisu 转自:http://blog.csdn.net/hguisu/article/details/7453390 1. 概念理解 在进行网 ...
- Linux设备驱动中的阻塞和非阻塞I/O
[基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作.被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到 ...
- 阻塞与非阻塞、同步与异步 I/O模型
I/O模型 Linux 下的五种I/O模型 阻塞I/O(blocking I/O) 非阻塞I/O (nonblocking I/O) I/O复用(select 和poll) (I/O multiple ...
- 聊聊阻塞与非阻塞、同步与异步、I/O模型
1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步: 所谓同步,就是在c端 ...
- socket阻塞与非阻塞,同步与异步、I/O模型
socket阻塞与非阻塞,同步与异步 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:同步: 所 ...
- Linux设备驱动中的IO模型---阻塞和非阻塞IO【转】
在前面学习网络编程时,曾经学过I/O模型 Linux 系统应用编程——网络编程(I/O模型),下面学习一下I/O模型在设备驱动中的应用. 回顾一下在Unix/Linux下共有五种I/O模型,分别是: ...
随机推荐
- Mvc中使用MvcSiteMapProvider实现站点地图之基础篇
MvcSiteMapProvider 是针对 ASP.NET MVC 中,提供菜单. 网站地图. 站点地图路径功能,以及更多的工具.它提供配置使用一个可插入的体系结构,可以是 XML. 数据库或动态生 ...
- C++异常处理的编程方法(阿愚,整整29集)
相遇篇 <第1集 初次与异常处理编程相邂逅> <第2集 C++中异常处理的游戏规则> <第3集 C++中catch(…)如何使用> <第4集 C++的异常处理 ...
- javascript数据类型、初始化
Javascript数据类型有6种: 数值型数据类型(Number): 字符串(String): 布尔型数据(Boolean): 对象数据(Object): 空(Null): 未定义(Undefine ...
- hdu1003
Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- Linux下的sudo及其配置文件/etc/sudoers的详细配置说明
http://www.osedu.net/article/linux/2011-01-03/178.html Linux下的sudo及其配置文件/etc/sudoers的详细配置说明 1.sudo介绍 ...
- IHttpModule接口事件执行 获取Session 找了很多国内的都不对,从国外转过来一个测试可用的
我的环境,asp.net4.0框架集 不多说上代码 public class MyHttpModule : IHttpModule { public void Init(HttpApplication ...
- mysql 1449 : The user specified as a definer ('montor'@'%') does not exist
grant all privileges on *.* to root@"%" identified by "."; flush privileges;
- SVN连接不上
某次我们部门换了场地.SVNserver就连接不上了,后来公司数据中心处理好后,还是连接不上,原来还需刷新自己电脑的DNS. 如需转载,请注明出处http://blog.csdn.net/combat ...
- Hadoop CLI MiniCluster
CLI MiniCluster Use the climonicluster, users can simply start and stop a single-node hadoop cluster ...
- How debuggers work
做了一个PPT用来和组内的同学交流一下.内容很简单,写得也很简单. 谁知道博客园文章里怎么直接嵌入PPT呢? link: http://www.slideshare.net/ssuserdc412f/ ...