高手讨论区,嘿嘿,阻塞与非阻塞的困惑
困惑之一:
使用阻塞怎么了?会带来什么后果?在什么情况之下?对性能有影响么?
困惑之二:
为何会阻塞?微软在实现上有何区别?
[解决办法]
阻塞就是发出的数据没有收,整个线程就处于等待状态,直到接收完之后,反之相同。
会使你程序没有响应,无法处理其它工作,在你只有一个线程的状态下。
CSocket默认阻塞,CAsyncSocket默认非阻塞
可以用ioctlsocket设置,使用FIONBIO标志;
[解决办法]
这也是高手问题?
[解决办法]
作业贴, 鉴定完毕
[解决办法]
知道同步和异步吗?
[解决办法]
使用阻塞怎么了?会带来什么后果?在什么情况之下?对性能有影响么?
套接字有两种模式,阻塞模式与非阻塞模式。默认创建的为阻塞模式.
在blocking model 下:
套接字在IO时阻塞应用程序,就是说控制权不会返回给应用程序,也就是说程序执行到此代码时会卡住。分两种情况,1.send函数时,只有把要发送的数据下传至TCP层,send这句代码才继续向下执行,此时可确认自己的数据已经在网络上传输了2.recv时,只有收到一定数据给应用程序缓冲区时,recv这行代码才会向下执行。如果不想这样做,可以使用多线程,或者选用其他网络IO模型。一般在做服务器程序时,不会使用阻塞套接字,性能低,数据吞吐率也不高。优点是此种模型编写难度较低,可以用来做入门的学习之用。
非阻塞套接字,IO会马上返回.但在send时,如果SOCKET缓冲区已满,会返回错误,使用WSAGetLastError会得到错误码为WSAEWOULDBLOCK,意思是说在一个非阻塞的套接字上,请求没有完成。recv时如果SOCKET缓冲区没有可以读的数据,也会返回WSAEWOULDBLOCK.
[解决办法]
nizhaorong 麻烦告诉我一下, 怎样能看到自己的星星。
一下纯属个人意见, 不对的地方,大家指教:
Socket 的模式大概分为这么几种:
1、 阻塞式的,Socket操作都需要将线程挂起,等待内核完成后才能返回。
如: 调用connect=> 进入内核=> Syn包=〉服务器返回SYN ACK 包=〉connect返回。
=〉ACK包发往服务器。
但一般来说,阻塞和非阻塞对于recv来说意义更大。
当在阻塞式的Socket上调用recv时,如果这时网络栈上没有数据给你接收,那么这时线程将
会挂起,直到有报文给你接收才返回。
这样就造成你的应用程序在企图接收数据时候,而网络栈上没有数据的时候就会被锁住。
有什么办法解决这个问题呢? 我们来介绍IO
2、 IO复用, 就是在企图读写数据的时候先询问下是否可读写, 如果不能,可以去干别的事情,不会造成死锁。
但是假如我们有大量的连接需要去频繁的查询可读写状态,每次查询都会和内核交互。这样会造成
效率低下。再介绍一种
3、 重叠IO. 就是一次查询多个Socket的状态。不用去来来回回的遍历。
另外,
在windows socket api 中还有一种消息机制, 就是把Socket状态通知到窗口。然后用消息去处理。
对于重叠IO, 在windows上还有完成端口模型,他和重叠端口相比, 不但能捕捉到IO事件, 而且内核已经替你完成了Socket IO, 比如read事件, 在内核通知你的时候,他已经帮你读好数据了, 并放在你指定的缓存中(这里是指在用户态下,事先为每个Socket分配的内存)。
为什么有这么多socket模式呢? 哪个更好呢?
为什么有,我不知道,可能是出于需求吧,
说说哪个更好?
孤立的来说,其实没有哪个更好? 只有哪个更适合你的应用应用环境。
如: 阻塞式的比较简单,方便,稳定。适合比较简单的客户端程序。
IO复用我认为它适合SocketIO操作比较少的情况。
重叠IO就适合高性能的服务器的开发, 另外完成端口是windows上比较公认的高性能服务器的网络开发模型。 当然, windows 的IOCP也有个坏处,就是需要大量的内存,应为前面说了他需要事先指定缓存。 不过高性能的 服务器,一般都不用windows平台。
windows的消息模型就比较适合有UI的应用程序。
当然, 有些模型的选择上可能还有个人爱好的因素,
如, 我可能不喜欢用消息模型,
我不喜欢被动的被通知, 而喜欢主动的去查询。
[解决办法]
还是作业贴,不用鉴定就知道了
[解决办法]
一般情况下,非阻塞模式更适合windows的消息机制。
[解决办法]
mark