关于send时产生WSAEWOULDBLOCK的处理

这篇博客探讨了在使用非阻断模式的Socket编程时,如何处理send函数返回WSAEWOULDBLOCK错误的情况。作者指出,这种错误表明发送窗口已满,但数据并未丢失,而是被系统缓存,等待窗口有空间时继续发送。文章讨论了阻断模式和非阻断模式的区别,并建议在非阻断模式下遇到WSAEWOULDBLOCK时,将待发送数据缓存,等待FD_WRITE事件触发后再发送。同时,作者提到使用select模型作为更高效的选择。
摘要由CSDN通过智能技术生成

 http://topic.csdn.net/t/20050328/11/3887277.html

 

搜索了一下论坛里关于send时产生WSAEWOULDBLOCK时的处理办法,得出如下结论:  
        1.产生这个错误只是说明out   buffer已经满了,不代表出错.  
        2.可以等待FD_WRITE消息,此时将没有发送完成的数据再次发送出去.  
   
        但还是有疑问,我的问题如下:  
        1.我上面的两条结论正确吗?  
        2.关于在FD_WRITE里把没有发送完的数据发送完,这一点如何做到呢?因为  
        int   nSended   =   send(mysock,   myBuf,   myLen,   0);  
        如果此时产生WSAEWOULDBLOCK,那么nSended肯定是SOCKET_ERROR,也就是-1了.此时nSended不能代表已经发送成功的字节数,那么在myBuf这个缓冲区里,究竟有多少字节是已经发送出去的,有多少数据是没有发送出去的呢?  
         
        在我的程序时,我想在得到WSAEWOULDBLOCK时,将没有发送完的数据缓冲起来,等到FD_WRITE时,再将这些数据发送出去.所以还请大侠们指点一下,在这种情况下,如何知道有多少数据是被发送了的.  
   
        :_) 问题点数:20、回复次数:16Top

1 楼foxwing(穿过你的骨髓我的手)回复于 2005-03-28 13:26:10 得分 20

首先要确定一点:send函数中的这个myBuf是应用程序提供的一个const类型的字符串(就以字符串为例吧),并不是所谓的“缓冲区”。我觉得其实不是缓冲区已满,而是发送窗口已满,缓冲区是系统动态分配的,一般来说是足够用的,不大容易出现缓冲区已满的现象。  
   
  我觉得过程是这样的:send函数先把数据传给Socket核心处理模块,核心处理模块负责管理这些需要发送出去的数据的内存堆栈,然后试着将这些数据包交付协议层的发送窗口,如果窗口大小足够,则核心驱动模块将数据包完全交付给窗口去发送,并删除暂存在自己内存堆栈上的数据;如果窗口大小不够(导致这种情况的原因有很多,比如接收端接收缓存已满;至于这个“窗口大小不够”这个消息到底是核心驱动模块经自己判断生成的,还是由协议层告知核心驱动模块的,这点我也不大清楚,也想搞明白),则将能交付的数据尽最大量交给窗口去发送,并将无法发送出去的那些数据暂存在核心处理模块的内存堆栈上,并同时向上给send函数发送一个发送窗口已满的消息,然后send函数便处于BLOCK状态。  
  可以确定的是,send函数不会直接和协议层打交道,而是通过核心驱动模块来和协议层交互(废话,呵呵)  
  另外,我觉得知道多少数据被发送是没有意义的,因为一旦将数据通过发送窗口发送出去,核心驱动模块就会将剩余的数据马上交付空的发送窗口,这个时间非常短,等你得到了发送数据的大小时说不定你要发送的所有数据已经发送出去了,从而返回你指定发送的数据大小。如果你的兴趣在于接收端的recv函数处于暂停接收状态(通过设置断点)而要求send函数返回发送窗口里的数据大小,我也有同样的兴趣,呵呵Top

2 楼jakkye(欧)回复于 2005-03-28 17:21:25 得分 0

好!!讲解的好,读了两遍,明白什么意思了...  
  呵呵...以前我一直认为send是直接跟协议层打交道的,但想一想有点不大现实,经这么一解释,霍然开朗型...  
  看来得去把<计算机网络>找出来,加强点原理性的东东了:)  
   
  多谢多谢:)Top

3 楼jakkye(欧)回复于 2005-03-28 17:37:09 得分 0

不过还有一个问题,很简单的一个程序,如下:  
        for(int   i=0;   i<=1000;   i++)  
        {  
              int   nSended   =   send(mySocket,   myBuf,   myLen,   0);  
        }  
  按照你的说法,send函数把myBuf这个字节数组上的内容交给了核心处理模块,那么,如果i==500的时候,nSended变成了SOCKET_ERROR,且WSAGetLastError()   ==   WSAEWOULDBLOCK,而此时这个XUN环并没有判断,还会进行接下来的500个循环,那是不是接下来的500个循环中,send()也都把数据交给核心处理模块了吗?那如果这个循环接下来还有50000个呢?"核心处理模块的内存堆栈"有这么大吗?  
   
        一旦WSAEWOULDBLOCK产生,那么接下来的send函数是如何动作的呢?是把待发送的数据放到"核心处理模块的内存堆栈"上了呢?还是其它什么

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值