2013-06-12 29 views
-2

我正在實現一個服務器,在該服務器中,我偵聽客戶端使用accept套接字調用進行連接。套接字呼叫之間的時間差距,即。 Accept()和recv/send calls

接受發生後,我收到套接字,我等待大約10-15秒,然後再進行第一次recv /發送呼叫。

發送到客戶端的呼叫失敗,errno = 32,即斷開管道。

由於我不控制客戶端,我在接受的套接字中設置了套接字選項* SO_KEEPALIVE *。

const int keepAlive = 1; 
acceptsock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_length) 
if (setsockopt(acceptsock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(keepAlive)) < 0) 
{ 
    print(" SO_KEEPALIVE fails"); 
} 

任何人都可以請告訴可能會出現什麼問題,以及我們如何防止客戶端套接字關閉?

注意 ,我想在這裏補充一點的是,如果沒有時間間隔或接受和發送/ recv的調用之間小於5秒,按預期發生在客戶端服務器通信。

+0

在Linux中,你可以得到errno = 32的錯誤:ENOTCONN也意味着 套接字沒有連接,並且沒有給出目標。請看你在發起send/recv之前所做的系統調用是不是返回錯誤 – Aravind

+1

在你開始調用send()之前,你確認了connect()實際上是否成功,並且通知你一個完整的連接可用?套接字在空閒時間後通常不會自行關閉,對於'SO_KEEPALIVE'來說,10-15秒的時間太短而無法關閉死連接,而10-15秒對於外部防火牆/路由器而言太短以至於無法關閉空閒連接。所以其他事情正在發生。我的猜測是你沒有正確管理你的客戶端套接字。 –

+0

@Aravind和Remy ..是的,connect()成功了,因爲接受阻塞的調用給出了一個有效的accpetsock。此外,在我開始收到錯誤32之前,客戶端也會收到兩次或三次數據。正如我已經提到,如果在接受和發送/接收呼叫之間沒有等待,我不擁有客戶端和客戶端的工作。 – Rajat

回答

0

connect(2)send(2)是客戶端進行的兩個獨立的系統調用。第一個啓動TCP three-way handshake,第二個實際排隊傳輸的應用程序數據。

在服務器端雖然,你能完成後立即啓動send(2) -ing數據連接的插座成功accept(2)(即不要忘記檢查acceptsock-1)。

+0

我想你不明白我的問題。謝謝澄清。請再次通過它。我正在執行對-1的檢查,因爲套接字是有效的。 – Rajat

+0

你必須解釋實際問題是什麼。添加更多信息,比如什麼應用程序級別的協議用於套接字,以及您認爲應該發生什麼。 –

0

After the accept happens and I receive the socket, i wait for around 10-15 seconds before making the first recv/send call.

爲什麼?你的意思是客戶需要很長時間才能發送數據?或者你只是在服務器上尋找accept()recv()之間10-15秒,如果是的話,爲什麼?

The send calls to the client fails with errno = 32 i.e broken pipe.

因此客戶端已關閉連接。

Since I don't control the client, i have set socket option SO_KEEPALIVE in the accepted socket.

這不會阻止客戶端關閉連接。

Could anyone please tell what may be going wrong here

客戶端正在關閉連接。

and how can we prevent the client socket from closing ?

你不行。

+0

總之你想說的是在這裏沒有什麼可以做的。我在等待,因爲有一些數據需要處理併發送給客戶端。所以沒有別的選擇,只能在發送數據給客戶端之前等待這些數據。 – Rajat

+0

@Rajat'總之'我已經說過了,用我選擇的話說:'你不能'。不要告訴我我想說什麼。我對這種事情極度過敏。我已經說過我想說什麼了,我不需要任何解釋。我注意到你沒有回答我的任何問題。 – EJP