8.1.2 非锁定模式
除了锁定模式,我们还可考虑采用非锁定模式的套接字。尽管这种套接字在使用上存在着些许难度,但只要排除了这项困难,它在功能上还是非常强大的。除具备锁定套接字已有的各项优点之外,还进行了少许扩充,功能更强。程序清单8 - 3向大家展示了如何创建一个套接字,并将其置为非锁定模式。
程序清单8-3 设置一个非锁定套接字

SOCKET s;
unsigned long u1 = 1;
int nRet;
s = SOCKET(AF_INET,SOCK_STREA,0);
nRet = ioctlsocket(s,FIOBIO,(unsigned long *)&ul);
if(nRet == SOCKET_ERROR)
{
 //Failed to put the socket into nonblocking mode
}

将一个套接字置为非锁定模式之后, Winsock API调用会立即返回。大多数情况下,这些调用都会“失败”,并返回一个W S A E W O U L D B L O C K错误。什么意思呢?它意味着请求的操作在调用期间没有时间完成。举个例子来说,假如在系统的输入缓冲区中,尚不存在“待决”的数据,那么r e c v(接收数据)调用就会返回W S A E W O U L D B L O C K错误。通常,我们需要重复调用同一个函数,直至获得一个成功返回代码。在表8 - 2中,我们对常见Wi n s o c k调用返
回的W S A E W O U L D B L O C K错误的含义进行了总结。
由于非锁定调用会频繁返回W S A E W O U L D B L O C K错误,所以在任何时候,都应仔细检查所有返回代码,并作好“失败”的准备。许多程序员易犯的一个错误便是连续不停地调用一个函数,直到它返回成功的消息为止。例如,假定在一个紧凑的循环中不断地调用r e c v,以读入2 0 0个字节的数据,那么与使用前述的M S G _ P E E K标志来“轮询”一个锁定套接字相比,
前一种做法根本没有任何优势可言。为此, Wi n s o c k的套接字I / O模型可帮助应用程序判断一个套接字何时可供读写。
锁定和非锁定套接字模式都存在着优点和缺点。其中,从概念的角度说,锁定套接字更易使用。但在应付建立连接的多个套接字时,或在数据的收发量不均,时间不定时,却显得极难管理。而另一方面,假如需要编写更多的代码,以便在每个Wi n s o c k调用中,对收到一个W S A E W O U L D B L O C K错误的可能性加以应付,那么非锁定套接字便显得有些难于操作。在这些情况下,可考虑使用“套接字I / O模型”,它有助于应用程序通过一种异步方式,同时对一个或多个套接字上进行的通信加以管理。
表8-2 非锁定套接字上的W S A E W O U L D B L O C K错误函数名说明

W S A A c c e p t和a c c e p t   应用程序没有收到连接请求。再次调用,便可检查连接情况
c l o s e s o c k e t          大多数情况下,这个错误意味着已随S O _ L I N G E R选项一道,调用了s e t s o c k o p t,而且已设定了一个非零的超时值
W S A C o n n e c t和c o n n e c t       应用程序已初始化。再次调用,便可检查是否完成
W S A R e c v、r e c v、W S A R e c v F r o m和r e c v f r o m 没有收到数据。稍后再次检查
W S A S e n d、s e n d、W S A S e n d To和s e n d t o 外出数据无缓冲区可用。稍后再试

Posted on 2006-09-12 11:10 艾凡赫 阅读(489) 评论(0)  编辑 收藏 引用 所属分类: 网络编程

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理