从缓冲上看阻塞与非阻塞socket在发送接收上的区别
2014-05-03 09:46
239 查看
从缓冲上看阻塞与非阻塞socket在发送接收上的区别 首先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。
相关文章推荐
- 南阳 249 最大长方形
- 如何在excel里面生产条形码(10分钟让你的excel里面出现条形码)
- MDT2012部署系列之09 镜像捕获配置
- MongoDB插入数据的3种方法
- 联想A820T 修改MAC
- linux vnc 与server共享同一个桌面
- nyoj-642-牛奶
- 单例模式--理解静态内部类实现线程安全的单例模式
- hdu-1342-Lotto(dfs)
- 经典白话算法之归并排序
- 最长有效括号长度
- 字符串完美度
- 汤姆·霍尔的快速成为游戏开发者的秘诀 顶级游戏设计大师谈如何成为一名游戏设计师!
- 项目经理应该把30%的时间用在编程上
- 做一朵素馨,淡雅于尘世
- JSP中九大内置对象详解
- python in action
- MongoDB查询技巧总结
- 各种大数据技术总结
- oracle异常之no_data_found