在阻塞模式的套接字上,调用任何一个Windows Sockets API都会消耗不肯定的等待时间。在调用recv()函数时,发生在内核中等待数据和复制数据的过程如图所示: 编程
当调用recv()函数时,系统会首先检查是否有准备好的数据。若是数据没有准备好,系统就处于等待状态。当数据准备好后,将数据从系统缓冲区复制到用户空间,而后该函数返回。在套接字应用程序中,当调用recv()函数时,用户空间未必就已经存在数据,此时recv()函数就会处于等待状态。
并非全部Windows Sockets API以阻塞套接字为参数调用都会发生阻塞。例如,以阻塞模式的套接字为参数调用bind()、listen()函数时,函数会当即返回。将可能阻塞套接字的Windows Sockets API调用分为如下四种:
1.输入操做
recv()、recvfrom()、WSARecv()和WSARecvfrom()函数。以阻塞套接字为参数调用该函数接收数据。若是此时套接字缓冲区内没有数据可读,则调用线程在数据到来前一直睡眠。
2.输出操做
send()、sendto()、WSASend()和WSASendto()函数。以阻塞套接字为参数调用该函数发送数据。若是套接字缓冲区没有可用空间,线程会一直睡眠,直到有空间。
3.接受链接
accept()和WSAAcept()函数。以阻塞套接字为参数调用该函数,等待接受对方的链接请求。若是此时没有链接请求,线程就会进入睡眠状态。
4.外出链接
connect()和WSAConnect()函数。对于TCP链接,客户端以阻塞套接字为参数,调用该函数向服务器发起链接。该函数在收到服务器的应答前,不会返回。这意味着TCP链接总会等待至少到服务器的一次往返时间。
使用阻塞模式的套接字,开发网络程序比较简单,容易实现。当但愿可以当即发送和接收数据,且处理的套接字数量比较少的状况下,使用阻塞模式来开发网络程序比较合适。
阻塞模式套接字的不足表现为,在大量创建好的套接字线程之间进行通讯时比较困难。当使用“生产者-消费者”模型开发网络程序时,为每一个套接字都分别分配一个读线程、一个处理数据线程和一个用于同步的事件,那么这样无疑加大系统的开销。其最大的缺点是当但愿同时处理大量套接字时,将无从下手,其扩展性不好。 服务器