套接字模式

来源:互联网 发布:linux 命令 竖线 编辑:程序博客网 时间:2024/05/18 03:48

套接字模式

套接字模式分为两种:阻塞(Blocking)模式和非阻塞(Non-Blocking)模式。所谓阻塞模式,是指当对一个被设为阻塞模式的套接字进行某些操作时(如send和recv),如果这些操作不能立即完成,那么它们将进入等待状态,直到操作完成或发生错误才返回。非阻塞则不一样,当对一个被设为非阻塞模式的套接字进行某些操作时,即使它们不能立即完成,也会马上返回,并且通过对返回值的分析,可以明确知道操作是否已完成。

  • 当一个套接字处于阻塞模式下,一个线程对其调用Winsock函数时,如果这些函数不能立即完成,那么该线程将被挂起,在函数返回之前不能在进行其他工作。这对于只处理单个连接的应用程序(比如简单的客户端)来说没有什么问题,但是对于需要处理大量客户连接的服务器程序来说,则是一个很严重的问题,如果每个客户连接都创建一个线程,则CPU将需要花费大量时间来进行线程间的切换和调度。程序性能会很差。
  • 当一个套接字处于非阻塞模式下,一个线程对其调用Winsoc函数时,无论该函数能不能立即完成,函数都将马上返回,也就是说线程并不会被挂起,但是线程必须对函数的返回值进行分析。如果函数的返回值表明不能完成指定的操作时,那么线程必须稍后再重试该操作(既再次调用该Winsock函数)。这就有一个问题,即线程该什么时候再次调用该函数才合适呢?合适的意思是指调用该函数时,能够确保其立即成功返回。最简单的办法就是循环调用这个函数,即如果函数返回WSAEWOULDBLOCK时,则继续对其调用,直到其能够立即成功返回为止,即返回值表面操作已经完成。这种方法也叫做Polling,即轮询。很明显,轮询会浪费大量的CPU时间。

通过上面对阻塞模式和非阻塞模式的分析,可以看到,它们都有各自的问题,为了解决这些问题,Winsock引入了各种不同的I/O模型,同时也让开发者能够编写高性能的网络应用程序。

同步与异步

同步与异步的概念,经常与阻塞与非阻塞弄混了。
同步与异步,它们是消息的通知机制。
1. 同步
所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。
举个最明显的例子就是SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的值返回给调用者。
函数原型:
LRESULT WINAPI SendMessage(
In HWND hWnd,
In UINT Msg,
In WPARAM wParam,
In LPARAM lParam
);
Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
2. 异步
所谓异步,相对同步,当一个异步过程调用发出后,调用者不会立刻得到结果。
实际处理这个调用的部件是在调用发出后,通过状态、通知来通知调用者,或通过回调函数处理这个调用。
举个例子SendMessageCallback ,相对SendMessage,它立刻返回,当窗口程序处理完消息后,系统调用指定的回调函数,将消息处理的结果和一个应用程序定义的值传给回调函数。
函数原型:
BOOL WINAPI SendMessageCallback(
In HWND hWnd,
In UINT Msg,
In WPARAM wParam,
In LPARAM lParam,
In SENDASYNCPROC lpCallBack,
In ULONG_PTR dwData
);
Sends the specified message to a window or windows. It calls the window procedure for the specified window and returns immediately if the window belongs to another thread. After the window procedure processes the message, the system calls the specified callback function, passing the result of the message processing and an application-defined value to the callback function.

阻塞与非阻塞

阻塞与非阻塞,指的是程序在等待消息(与同步异步无关)时的状态(一般情况下是套接字)。
1. 阻塞
阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。(不要与同步混淆,对同步调用来说,很多时候当前线程还是激活的,只是当前函数还没有返回而已)
socket接收函数recv是个阻塞调用的例子,当socket工作在阻塞模式的时候,如果还没有数据到达,当前线程会被挂起,直到有数据为止。
2. 非阻塞
非阻塞,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

参考资料:
https://www.zhihu.com/question/19732473
http://blog.chinaunix.net/uid-26000296-id-3754118.html

0 0