2010-02-26 52 views
1

我一直在閱讀手冊頁進行閱讀(2),根據手冊頁,read(2)的返回值在錯誤時爲-1,在EOF上爲0,並且讀取的字節數大於0。如何確定我是否完成從UNIX套接字讀取()?

如何判斷客戶端寫入(2)何時完成?我想問,因爲我正在寫一個服務器和一個客戶端來測試它,但是當我第一次讀取(2)並循環查看更多內容時,請閱讀(2)塊並等待另一次寫入(2) )(這不是因爲我的客戶端只有一個寫(2))。

如果我只是缺少一些簡單的東西,有人可以指出它或指出我很好的參考?

+1

男人,這是一個很常見的問題。 – ChaosPandion 2010-02-26 16:51:14

+0

本質上是這樣的一個騙局:http://stackoverflow.com/questions/2306481/net-newbie-socket-problem – ChaosPandion 2010-02-26 16:52:58

回答

3

客戶端在完成時需要關閉套接字。一旦客戶端關閉套接字,服務器將收到EOF消息。如果客戶端打開套接字但從不寫入,服務器將永遠等待另一條消息下來。

+0

什麼時候客戶端和服務器有多個讀/寫?挪亞建議我是否必須開始使用標題? – 2010-02-26 17:00:29

+1

你真的不應該關閉套接字來接收一條消息。我認爲賈斯汀的回答是正確的。 – ChaosPandion 2010-02-26 17:05:35

+0

@Chaos,我明白OP只希望*發送/接收一條消息。 @Alex,如果你想接收多條消息,那麼你可以按照Noah的建議使用信號,在當前消息中添加一個頭字節數或者使用面向消息的協議。 – 2010-02-26 17:31:25

2

你知道你做的時候read回報:

  • -1 - 發生錯誤
  • 0 - EOF
  • 另外,非零值 - 這是最常見的情況。您的協議需要使用指定消息大小的標頭或固定長度消息來指定其消息的大小。然後,您可以跟蹤讀取的字節數,並且一旦讀取了很多字節,就知道您已經完成了。否則,您需要繼續閱讀字節,直到您收到完整的消息。
+0

所有這一切都在問題中說明。 – noah 2010-02-26 16:57:02

+1

@noah - 你讀了列表中的最後一項嗎? – ChaosPandion 2010-02-26 16:59:36

+0

@Chaos - 確實如此。 @noah - 前兩個提到,但最後(也是最重要的!)子彈不是。關鍵是你需要另一種從套接字讀取多個消息的策略。除了我描述的方法之外,您還可以根據您的建議使用分隔符,並提供一些注意事項。 – 2010-03-14 16:46:05

0

讀寫之間沒有對應關係。單個客戶端寫入可能需要10次讀取才能完全加載。除非您在內容中添加分隔符,否則無法知道結束位置,除非套接字已關閉。

如果您仍然需要發送給客戶端的響應,你可以半關閉套接字在客戶端上:

shutdown(socket, SHUT_WR); 

,這將導致在服務器上讀取返回0。

+0

你建議什麼樣的分度?你怎麼知道分隔符不會出現在消息數據中? – 2010-02-26 17:08:25

+0

我認爲他的意思是像一個空字符。 (如果您正在發送文本)。 – ChaosPandion 2010-02-26 17:09:10

+0

只要客戶端在數據正常出現時將其轉義,您就可以使用任何您想要的分隔符。但除非需要連接保持打開狀態,否則(一半)關閉插座是更好的選擇。 – noah 2010-02-26 20:59:09

0

東西看看會先用select()來檢查數據,並指定一個合適的超時期限,而不是隻是一味地調用read()。這將允許您的服務器在一段時間不活動後關閉套接字,並釋放可能使用的任何資源等。