第五章操作模式
5.1 什么是操作模式
Windows Sockets将操作模式分为3种完全不同的类型,它们分别是:阻塞模式、非阻塞模式和异步模式。我们可以通过将它们与打电话时所遇到的3种“操作模式”做比较来形象的了解这3种操作模式。我们在打电话时拨号并得到响应信号,但是我们想要与之童话的人这会儿不再电话旁,在这种情况下,可选操作如下:
1. 不挂机,等待,直到对方过来接电话。
2. 挂机,之后再打电话过去。
3. 留言,让对方打过来。
5.1.1不挂机,等待:阻塞
在等待对方来接电话的过程中,我们可能做不了多少别的事,最多可以和别人聊聊天或者做点手头工作,但是无法使用电话。这与阻塞模式非常类似:可以腾出手来做点别的事,但是你进行的网络操作不能超过一个。
在阻塞模式中,Windows Sockets 函数只有当操作完成时才返回,结果可能成功,也可能失败,但是无论是哪一种情况,你都在函数返回前知道操作完成了。
在非抢占式任务系统中,WinSock DLL正在处理一个阻塞式函数调用时,它会让位于其他应用程序。由于在一个阻塞式函数调用没有完成时,是不能调用任何其他WinSock函数,这就使得接收消息成为一个大问题,因为这通常要在阻塞操作正在进行时发起网络操作。在阻塞情境(blocking context)中,代码需要恰当地处理这种重入消息。
5.1.2挂机后再拨:非阻塞
如果你挂机,稍后再拨,那么需要确定什么时候再拨以多长时间拨一次。如果不断地拨号,那是在浪费生命。你希望在呼叫之间做点其他的事情。这与非阻塞式操作相似:在操作完成过程中需要“探询”,但是你不想探询得太频繁,导致浪费系统资源。
在非阻塞操作模式中,Windows Sockets函数调用立即返回,有些情况下返回值表明成功,但是有些却表明失败。不过,非阻塞操作模式中的函数调用失败并不一定就是坏事。错误值(函数失败后调用WSAGetLastError()返回)有可能是WSAEWOULDBLOCK,其字面上的意思是“如果必须等待操作完成才能返回,那么函数应该阻塞才对”。
根据函数的不同,WSAEWOULDBLOCK的含义可能代表两种情况之一:或者表示WinSock DLL已经开始了操作,但是目前还没有完成(及操作还在等待之中);或者表示WinSock作了尝试,但在当下无法满足操作请求。在前一种情况下,操作最后总要完成,并且有若干种方法来检测操作是否完成;在后一种情况下,WSAEWOULDBLOCK错误信息表明用户需要再次调用函数。
5.1 什么是操作模式
Windows Sockets将操作模式分为3种完全不同的类型,它们分别是:阻塞模式、非阻塞模式和异步模式。我们可以通过将它们与打电话时所遇到的3种“操作模式”做比较来形象的了解这3种操作模式。我们在打电话时拨号并得到响应信号,但是我们想要与之童话的人这会儿不再电话旁,在这种情况下,可选操作如下:
1. 不挂机,等待,直到对方过来接电话。
2. 挂机,之后再打电话过去。
3. 留言,让对方打过来。
5.1.1不挂机,等待:阻塞
在等待对方来接电话的过程中,我们可能做不了多少别的事,最多可以和别人聊聊天或者做点手头工作,但是无法使用电话。这与阻塞模式非常类似:可以腾出手来做点别的事,但是你进行的网络操作不能超过一个。
在阻塞模式中,Windows Sockets 函数只有当操作完成时才返回,结果可能成功,也可能失败,但是无论是哪一种情况,你都在函数返回前知道操作完成了。
在非抢占式任务系统中,WinSock DLL正在处理一个阻塞式函数调用时,它会让位于其他应用程序。由于在一个阻塞式函数调用没有完成时,是不能调用任何其他WinSock函数,这就使得接收消息成为一个大问题,因为这通常要在阻塞操作正在进行时发起网络操作。在阻塞情境(blocking context)中,代码需要恰当地处理这种重入消息。
5.1.2挂机后再拨:非阻塞
如果你挂机,稍后再拨,那么需要确定什么时候再拨以多长时间拨一次。如果不断地拨号,那是在浪费生命。你希望在呼叫之间做点其他的事情。这与非阻塞式操作相似:在操作完成过程中需要“探询”,但是你不想探询得太频繁,导致浪费系统资源。
在非阻塞操作模式中,Windows Sockets函数调用立即返回,有些情况下返回值表明成功,但是有些却表明失败。不过,非阻塞操作模式中的函数调用失败并不一定就是坏事。错误值(函数失败后调用WSAGetLastError()返回)有可能是WSAEWOULDBLOCK,其字面上的意思是“如果必须等待操作完成才能返回,那么函数应该阻塞才对”。
根据函数的不同,WSAEWOULDBLOCK的含义可能代表两种情况之一:或者表示WinSock DLL已经开始了操作,但是目前还没有完成(及操作还在等待之中);或者表示WinSock作了尝试,但在当下无法满足操作请求。在前一种情况下,操作最后总要完成,并且有若干种方法来检测操作是否完成;在后一种情况下,WSAEWOULDBLOCK错误信息表明用户需要再次调用函数。