2011-03-22 49 views
3

我有一個監聽器將任意數據HTTP請求傳遞到網絡套接字然後通過TCP傳遞。這適用於第一個請求,但偵聽器不接受後續的新請求。接受多個後續連接到套接字

我的問題是:

如果我有sock=accept(listener,(struct addr *)&sin, &sinlen);然後,基於socket函數參考,監聽套接字保持打開狀態,我應該能夠重新調用accept()後續請求任意次數。它是否正確?如果是這樣,有人可以比我更熟悉套接字編程,請解釋此代碼可能看起來如何?

回答

8

是的,你可以accept()很多次在監聽套接字。爲了服務多個客戶端,你需要避免阻塞I/O - 也就是說,你不能直接讀取套接字並阻塞,直到數據進入。有兩種方法:你可以在每個客戶端自己的線程(或其自己的進程,在UNIX系統上使用fork()),或者您可以使用select()select()函數是一種檢查數據是否可用於任何一組文件描述符的方法。它在UNIX和Windows上均可用。

+5

你忘了一個選項,你也可以fork這是傳統的Unix處理事物的方式。 – 2011-03-22 15:42:55

+0

你是對的。 – 2011-03-22 15:47:25

+0

如果使用單獨的線程,則不需要避免阻塞I/O。 – EJP 2014-01-24 00:33:32

0

是的,你有正確的想法。

雖然我的C socket編程有點生疏,但在服務器套接字上調用accept會將通信通道設置回套接字的客戶端。在將來的連接嘗試中調用accept會建立多個套接字通道。

這意味着應該注意不要用特定連接的數據覆蓋單個共享結構,但它聽起來不像是那種容易出錯的錯誤。

4

這是Beej's Guide to Network Programming的一個簡單示例。

while(1) { // main accept() loop 
    sin_size = sizeof their_addr; 
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); 
    if (new_fd == -1) { 
     perror("accept"); 
     continue; 
    } 

    inet_ntop(their_addr.ss_family, 
     get_in_addr((struct sockaddr *)&their_addr), 
     s, sizeof s); 
    printf("server: got connection from %s\n", s); 

    if (!fork()) { // this is the child process 
     close(sockfd); // child doesn't need the listener 
     if (send(new_fd, "Hello, world!", 13, 0) == -1) 
      perror("send"); 
     close(new_fd); 
     exit(0); 
    } 
    close(new_fd); // parent doesn't need this 
} 

子進程 - 後fork() - 異步從accept()荷蘭國際集團的母公司進一步的連接處理的通信。

+0

一個簡單的鏈接不是一個答案。 – EJP 2014-01-24 00:34:03

+0

有時候是這樣。 – 2014-01-24 02:43:30

+0

請[僅限鏈接回答](http://meta.stackoverflow.com/tags/link-only-answers/info)。答案是「幾乎不超過一個外部網站的鏈接」[可能會被刪除]。 – Quentin 2014-01-24 23:36:18