2011-09-22 81 views
2

我有一個現有的多線程應用程序,它使用阻塞connect()調用。套接字連接超時在c使用輪詢

但是,我想介紹應用程序的連接超時,如果服務器在x毫秒內沒有響應我們的查詢,應用程序將停止嘗試並給出錯誤。

但是,我無法弄清楚如何使用民意測驗。

@caf的非阻塞連接使用選擇有很大的幫助。 但我已經閱讀,選擇較慢比較民意調查,因此我想使用民意調查。你能告訴我這是真的嗎?

我從the post粘貼一行代碼,這裏

int main(int argc, char **argv) { 
u_short port;    /* user specified port number */ 
char *addr;     /* will be a pointer to the address */ 
struct sockaddr_in address; /* the libc network address data structure */ 
short int sock = -1;   /* file descriptor for the network socket */ 
fd_set fdset; 
struct timeval tv; 

if (argc != 3) { 
    fprintf(stderr, "Usage %s <port_num> <address>\n", argv[0]); 
    return EXIT_FAILURE; 
} 

port = atoi(argv[1]); 
addr = argv[2]; 

address.sin_family = AF_INET; 
address.sin_addr.s_addr = inet_addr(addr); /* assign the address */ 
address.sin_port = htons(port);   /* translate int2port num */ 

sock = socket(AF_INET, SOCK_STREAM, 0); 
fcntl(sock, F_SETFL, O_NONBLOCK); 

connect(sock, (struct sockaddr *)&address, sizeof(address)); 

FD_ZERO(&fdset); 
FD_SET(sock, &fdset); 
tv.tv_sec = 10;    /* 10 second timeout */ 
tv.tv_usec = 0; 

if (select(sock + 1, NULL, &fdset, NULL, &tv) == 1) 
{ 
    int so_error; 
    socklen_t len = sizeof so_error; 

    getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len); 

    if (so_error == 0) { 
     printf("%s:%d is open\n", addr, port); 
    } 
} 

close(sock); 
return 0; 

}

你能幫我使用輪詢來寫類似的功能。

我在RHEL上並使用gcc 4.5.x版本。

更新:對於當前代碼,一旦應用程序創建連接到服務器,如何將套接字更改爲阻止模式。我無法找到解除這個O_NONBLOCK的方法。 更新2:fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) & ~O_NONBLOCK); One post指出我們可以用上面的命令做到這一點。雖然沒有得到登錄。

+0

select對此完全沒問題。 –

+1

我認爲民意調查和選擇都很慢。 [Check here。](http://daniel.haxx.se/docs/poll-vs-select.html) –

+1

實際上,我需要構建solaris和Linux complienet代碼。因此我不能去epoll()。需要接受民意調查或選擇。 –

回答

4

如果只有幾個正在輪詢的文件描述符,select()和poll()相對於其他系統相關輪詢API的性能是等效的。它們都縮小比例,但是當節目只聽幾個fds時可以表現得很好。

其他特定於系統的輪詢API的優點往往是它們會將關聯狀態推入內核,以便每個輪詢系統調用不需要從用戶空間到內核空間的狀態副本。只有少數事件,這種複製和掃描開銷並不重要,並且這種好處不存在。

只要堅持使用select(),除非需要擴展以處理數百或更多的fds。

如果你真的會處理很多fds,並且你必須同時支持Linux和Solaris,可以考慮使用類似於libeventlibev的庫來抽象出特定於內核的高效等待API。

-1

select不會比輪詢慢。但即使是這樣,在您的應用程序中最小的差異也不大可能發生。

要進行非阻塞超時連接,您可以從提供此類功能的現有應用程序進行復制。 (例如參見here,瞭解如何做到這一點)。

+0

哦對不起,我看到你遲到了,你已經有了代碼用於非阻塞連接與選擇。 – rumpel