在網絡協議實現時,在很多時候,我方在特定時刻并不清楚對方會進行怎樣的操作,是發送數據、發起連接、關閉連接還是什么也不做。此時在程序中我們采用的第一種方法是循環檢測:
while(TRUE)
{
if(recv()>0)
{
…
}
if(accept()!=SOCK_ERR)
{
…
}
}
當然這種方法是可以的,但是必須注意的是最好采用非阻塞模式運行recv()、accept(),因為如果是阻塞模式在recv()和accept()中會阻塞,此時如果正運行recv()則無法立即響應接受連接,如果正運行accept()則無法立即接收數據。
實際上,ZLIP提供了靈活的機制方便進行復雜的網絡協議編程,這些機制包括:
1. 使用select函數編程。
2. 使用類MFC回調機制。
3. 在us/os-II中使用ZLIP。
這里先介紹第一種:使用select函數編程。select()提供了同時檢測多個套接字狀態的機制,只要其中的一個套接字發生了預期的收到數據、接受連接、被關閉事件后,select()會立即返回,返回后用戶可以檢測是哪個套接字發生了事件,并做相應的處理。實例程序test_complex_send_recv就是使用select函數編程的典型例子。使用select()編程有如下的固定模式:
while(TRUE)
{
/* 清空測試集,準備開始新的檢測 */
FD_ZERO(&r);
FD_ZERO(&w);
/* 將需要檢測的套接字放入讀測試或寫測試集中 */
FD_SET(sc[0], &w);
FD_SET(sc[0], &r);
FD_SET(sc[1], &w);
FD_SET(sc[1], &r);
/* 等待相應的事件發生 */
select(0, &r, &w, NULL, NULL);
/* 是否為sc[0]可讀*/
if(FD_ISSET(sc[0], &r))
{
…
}
/* 是否為sc[0]可寫*/
if(FD_ISSET(sc[0], &w))
{
…
}
/* 是否為sc[1]可讀*/
if(FD_ISSET(sc[1], &r))
{
…
}
/* 是否為sc[1]可寫*/
if(FD_ISSET(sc[1], &w))
{
…
}
}