如果我采用WSAAsyncSelect这种IO模型,那么默认情况下套接字是非阻塞的、所有事件处理都是异步的也就是非阻塞的,那如果我在此基础上:
BOOL bNonBlock = FALSE; 
ioctlsocket(s, FIONBIO, &bNonBlock); 
这样以后,套接字就变成阻塞的了,我想问这样的操作会导致什么后果吗?本来的异步事件处理会不会因为阻塞的套接字而也相应变成同步事件处理了?PS.一直不太理解 一个套接字是阻塞或是非阻塞 对整个IO模型有什么影响?难道把套接字设置成阻塞的,那send的就自动变成阻塞了么?~而把套接字设置成非阻塞的,那send函数就变成非阻塞了??

解决方案 »

  1.   

    1 一个套接字是阻塞的,那么它的send函数就是阻塞的. 
      一个套接字是非阻塞的,那么它的send函数就是非阻塞的.
    2 套接字模型与I/O模型的关系:
      套接字模型是定义一个SOCKET的行为方式.阻塞的SOCKET, 它在执行SEND时,发送不成功,SEND函数不会返回,程序也就不能向下执行. 非阻塞send, 成功不成功都返回,根据返回值来判断是否成功.如果不成功,你还要继续的调用.
      I/O模型是当你的程序中有多个SOCKET的话, 如何管理它们以让他们达到最高的工作效率.
       比如说wsasyncselect模型, 把一个socket和一个windows procedure联系起来,把这个socket设成非阻塞的,它send了一个数据返回了,即使他不成功,你也不用再来调用了,当它可以发送时,OS会给windows procedure发消息的. 如何你把它改成阻塞的了,那么你就失去了使用I/O模型的意义了.
      

  2.   

    LS的兄弟说的很有道理,但我还有有些地方不明白,比如winsock2里实现了一些WSA函数,这些函数都是异步函数,比如WSASEND(),那我什么时候该用send什么时候该用WSASEND呢?我也可以把套接字设置成非阻塞的,那么这个时候send和WSASEND又有什么区别呢??
      

  3.   

    这个问题要看你连接哪个库 send wsasend 区别在于 后者支持重叠IO 和完成通知,以及以完成端口实现应用.两者最终都调用同一内部函数socket->provider->_wsasend,也就是说send是简化版的wsasend
      

  4.   

    那LS兄弟的意思是  如果我不涉及到 “重叠IO 和完成通知,以及以完成端口实现应用”,那send和WSASEND并没有什么区别吧(除了默认情况下一个是同步函数,一个是异步函数,,其他的并没区别吧)
      

  5.   

    那send的就自动变成阻塞了么?~而把套接字设置成非阻塞的,那send函数就变成非阻塞了??结果却是是这样,但是,send不管是阻塞还是非阻塞,一般都会成功,想象端口建立好好的怎么会发送不出去?区别在于recv,如果是阻塞的话,接收不到数据程序就卡在那,如果是非阻塞则可以避免这种状况了
      

  6.   

    应该可以这样说.基本上没有大的差别了.但是wsasend的第二和第三个参数的意思也不同于send.
      

  7.   

    那套接字设置成阻塞的,WSASEND函数会不会变成阻塞函数呢??
      

  8.   

    有两个函数可以生成一个套接字,一个是socket(), 一个是WSAsocket(), 如果你用WSAsocket()生成一个套接字,然后调用WSAsend()函数,并在该函数中传递了overlapped参数,那可以肯定的是它不会阻塞,即使这个套接字是阻塞模式. 如果是用socket()函数生成的套接字,估计会阻塞.
      

  9.   

    CAsyncSocket CSocket我也很迷惑,所以我直接用socket接口函数。。
      

  10.   

    不能确定.还与你的套接字支不支持overlapped属性和你的wsasend里的overlapped参数是不是NULL有关.