2016-02-04 185 views
2

我試圖設置一個接收套接字函數沒有成功的超時。我希望接受功能塊直到超時延遲結束。 是否可以不設置接受功能非阻塞? 我嘗試過很多可能性而沒有成功。接受套接字函數超時

感謝您的回答。

下面是我的代碼:

struct timeval tv; 
fd_set readfds; 

tv.tv_sec = 1; 
tv.tv_usec = 0; 

int s, s_remote; 
struct sockaddr_un remote; 
struct sockaddr_un local; 

if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 
    perror("socket"); 
    exit(1); 
} 

FD_ZERO(&readfds); 
FD_SET(s, &readfds); 

if (select(s+1, &readfds, NULL, NULL, &tv) > 0) { 

    printf("Waiting for a connection...\n"); 

    memset(&local, 0, sizeof(local)); 
    local.sun_family = AF_UNIX; 
    strcpy(local.sun_path, SOCK_PATH); 
    unlink(local.sun_path); 

    if (bind(s, (struct sockaddr *)&local, sizeof(local)) == -1) { 
    perror("UnixSocketClient :: error bind.\n"); 
    close(s); 
    return -1; 
    } 

    if (listen(s, 5) == -1) { 
    perror("UnixSocketClient :: error listen.\n"); 
    close(s); 
    return -1; 
    } 

    socklen_t remote_len = sizeof(remote); 
    printf("Accept :\n\r"); 

    if ((s_remote = accept(s, (struct sockaddr *)&remote, &remote_len)) == -1) { 
    perror("UnixSocket :: error accept.\n"); 
    return -1; 
    } 
    printf("Client accepted\n\r"); 
} 
+0

可能重複的[如何接受套接字超時](http://stackoverflow.com/questions/14045064/how-to-accept-socket-with-timeout) –

+0

由於您已經有一個'選擇'循環設計,爲什麼不在進入'select'循環之前調用'bind'和'listen',將套接字設置爲非阻塞狀態,並使用'select'來知道何時調用accept。 (你的設計已經被打破,處於阻塞和非阻塞設計之間,你爲什麼選擇's'') –

回答

2

你的代碼沒有意義。你必須調用:

  • 插座()
  • bind()的
  • 聽()
  • 選擇()
  • 接受()
的順序

+0

在接受之前移動選擇來解決我的問題。 – Tekros

0

的監聽套接字調用select()與超時設置和來電accept()如果select()沒有超時。

+0

他說他不想設置非阻塞套接字。按照你的計劃,如果在他接受「接受」的時候連線已經消失,他可以永遠等待。 –

+0

@DavidSchwartz我不明白你的觀點。如果他選擇超時,他怎麼能永遠等待? – EJP

+2

@EJP假設有一個輸入連接,他從'select'返回,但是當他調用accept時,連接就沒有了。他的「接受」可以永遠等待(或直到有新的連接進入)。所以要使用這種方法,他必須*設置非阻塞套接字,這是他特別說他不想做的事情。 'select'函數只是當前狀態的一個報告(就像'access'或'stat') - 它沒有提供未來的保證。 (這是一個常見的錯誤,並且在過去造成了嚴重的安全隱患,導致了嚴重的缺陷。) –