2015-01-06 107 views
0

我正在使用TCP套接字建立服務器 - 客戶端連接。每當我關閉客戶端套接字時,我的服務器也關閉。但是我只想關閉我的客戶端,我的服務器必須等待下一個accept()關閉客戶端套接字並保持服務器套接字處於活動狀態

服務器端:

{ 
bind(lfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr)); 
listen(lfd, 10); 
    while(1) 
    { 
     cfd = accept(lfd, (struct sockaddr*)NULL, NULL); 
    //server must wait here after client closes the connection application code 
     close(lfd); 
    } 
} 

客戶端:

inet_pton(AF_INET, argv[1], &serv_addr.sin_addr); 
connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); 
// ... application code 
if(c == 1) 
    close(fd); 
+0

查找TCP套接字多線程/ multiconnection例子,看看如何做到這一點。例如。在Codeproject.com – i486

+0

訣竅是分叉一個新的進程來處理新的連接。然後在您的子進程運行查詢完成時繼續運行主進程。如果你使用線程(你可以),那麼你需要確保線程不會關閉其他的套接字 - 因爲線程共享相同的堆。 – Owl

回答

0

的TCP由描述符所描述lfd監聽套接字被用於在一個特定的端口等待TCP傳入連接。在accept的調用之後,將創建一個新的套接字描述符,在您的示例中爲cfd

服務器和客戶端之間的所有數據交換均使用cfd執行。如果客戶端首先關閉套接字,服務器端可能的sendrecv將返回-1並帶有合適的errno值。

如果您希望服務器關閉連接,則應在使用shutdown(cfd, SHUT_RDWR)close(cfd)之後,而不是close(lfd)。這可讓lfd套接字處於打開狀態,允許服務器在accept上等待下一個傳入連接。 lfd應在服務器終止時關閉。

shutdown()提供了更大的靈活性,可在永久終止通信之前發送或接收剩餘數據。

+0

你的意思是'shutdown'(不是'close')? –

+0

是的,我的錯誤。但close()也會起作用。基本的區別在於,關機允許您接收任何待處理的數據,而使用close()時,套接字將立即銷燬。 – Manos

+0

順便說一句,你犯了一個錯字('close',而不是* clode *) –

0

接受調用將返回連接到客戶端的新套接字描述符(cfd在您的代碼中),因此當客戶端關閉其連接時,cfd將被關閉,而不是lfd。只要服務器需要,您可以使用lfd(偵聽套接字)接受連接。還應考慮在客戶端代碼中關閉(fd)之前調用shutdown。

3

當您在服務器端accept時,僅爲該客戶端生成一個新的套接字。

當你完成處理的客戶端,您必須close()套接字,(這是close(cfd)在您的術語)。您可以可能shutdown()套接字 - 這將影響套接字如何在TCP級別關閉。但無論你做或不做shutdown(),你必須close()它,否則你會泄漏FD。

你一定不能close()你聽fd(lfd在你的程序中),直到你打算不再接受任何連接。

TLDR:改變close(lfd)close(cfd)

相關問題