2009-05-21 149 views
3

如果我有一個文件描述符(套接字fd),如何檢查此fd是否適用於讀/寫? 在我的情況下,客戶已連接到服務器,我們知道fd。 但是,服務器會斷開socket連接,有沒有什麼線索可以檢查它?檢查套接字文件描述符是否可用?

回答

4

你想fcntl()檢查讀/寫設置在FD:

#include <unistd.h> 
#include <fcntl.h> 

int r; 

r = fcntl(fd, F_GETFL); 
if (r == -1) 
     /* Error */ 
if (r & O_RDONLY) 
    /* Read Only */ 
else if (r & O_WRONLY) 
    /* Write Only */ 
else if (r & O_RDWR) 
    /* Read/Write */ 

但是,這是指從插座不再連接一個單獨的問題。如果你已經在使用select()poll()那麼你幾乎就在那裏。如果您在events中指定POLLERR並在revents中檢查它,poll()將很好地返回狀態。

如果您正在執行正常的阻塞I/O,那麼只需在處理讀取/寫入錯誤時進入並正常恢復。

0

您可以使用select()poll()

-1

那麼,你可以調用select()。如果服務器斷開連接,我相信你最終會得到一個返回的錯誤代碼。如果沒有,你可以使用select()來告訴你網絡堆棧是否準備發送更多數據(或接收它)。

+0

我想`select`可能引發如果遠端斷開,* exceptfds *參數不會返回任何錯誤 – 2011-04-12 12:53:25

0

在C#,這個問題得到解答here

一般來說,插座斷開是異步的,並且需要被輪詢以某種方式。如果套接字上的異步讀取通常會關閉,那麼通常會返回該信息,從而使您有機會更快地獲取狀態更改。 Winsock(Windows)有能力註冊接收斷開連接的通知(但是,在另一方「消失」之後,這可能不會發生很長時間),除非您使用某種類型的「keepalive」(SO_KEEPALIVE,由默認情況下可能不會注意到幾個小時,或應用程序級的心跳)。

0

我發現的recv可以檢查。當套接字fd是壞的,有些errno設置。

ret = recv(socket_fd, buffer, bufferSize, MSG_PEEK); 
if(EPIPE == errno){ 
// something wrong 
} 
+0

EPIPE並不意味着套接字FD是壞的,這意味着連接中斷,不是一回事。 – EJP 2016-12-13 23:33:02

相關問題