2014-11-03 37 views
1

我對在Unix上用C寫入/讀取一個套接字的字節數有些懷疑。我習慣於發送1024個字節,但是當我發送短字符串時,這實際上太多了。我從文件中讀取一個字符串,我不知道這個字符串有多少個字節,它每次都可以變化,它可以是10,20或1000.我只知道它是< 1024。所以,當我編寫代碼時,我不知道在客戶端讀取的字節大小(在服務器上,我可以使用strlen())。因此,無論我從文件讀取的字符串的長度如何,總是讀取最大字節數(本例中爲1024)的唯一解決方案?我應該讀/寫多少個字節的套接字?

例如,使用此代碼:

read(socket,stringBuff,SIZE); 

不會是如果SIZE是10,而不是1024,如果我想讀一個10字節的字符串更好?

+0

'recv()'返回通過套接字接收的字節數。 – timrau 2014-11-03 02:38:09

+1

請不要使用一個問題來宣傳不同的問題。 – 2014-11-03 02:39:27

+0

@timrau是的,我知道,也讀過,但如果我沒有錯,當你寫一個讀取調用時,你應該寫一些像read(socket,stringBuff,SIZE)的東西,並且在SIZE中你必須指定你想閱讀的字符數。 Whant我的意思是,如果我讀取了10個字符串,如果SIZE是10而不是1024,那麼它會更好嗎? – testermaster 2014-11-03 02:40:14

回答

4

在你的問題的代碼中,如果只有10個字節被讀取,那麼SIZE是10字節,1024字節還是1,000,024字節 - 它仍然只是讀取10個字節沒有區別。唯一的區別是你爲它預留了多少內存,如果你可能接收到一個高達1,024字節的字符串,那麼你將不得不放棄那麼多的內存。

但是,無論您嘗試讀入多少字節,您都必須爲read()實際讀取其中不同數量的可能性做好準備。特別是在網絡上,當你的傳輸延遲時,即使你的服務器發送了一個1,024字節的字符串,當你的客戶端調用read()時,你可能讀到的字節數也少於這個數字, 1024。

因此,您總是需要準備好接受多個read()電話的輸入。這意味着你需要能夠告訴你什麼時候閱讀完輸入內容 - 你不能單獨依靠read()已經返回來告訴你已完成的事實。如果您的服務器在閱讀第一個消息之前可能會發送多條消息,那麼您顯然不希望依賴此消息。

您有三個主要選項:

  1. 總是發送哪都一樣大小的郵件,或許填充小串用零如果必要的。對於TCP流,這通常不是最佳的。只要閱讀,直到你收到了這個字節數。

  2. 有一些哨點機制來告訴你消息何時結束。這可能是一個換行符,一個CRLF,一個空白行,或一行後面跟着一個空白行,或任何適用於您的協議的單個點。繼續閱讀,直到你收到這個哨兵。爲了避免一次對一個字符進行低效率的系統調用,您需要實現某種緩衝機制以使其正常工作。如果您可以確定您的服務器正在向您發送以單個'\n'字符終止的行,則可以使用fdopen()和標準C I/O庫。

  3. 讓你的服務器告訴你消息有多大(無論是在初始固定長度字段中,還是使用來自第2點的相同種類的標記機制),然後繼續閱讀直到獲得了該字節數。

+0

謝謝,完美答案! :) – testermaster 2014-11-03 03:10:41

2

read()系統調用塊,直到它可以讀取一個或多個字節,或直到發生錯誤。

它不能保證它會讀取你請求的字節數!對於TCP套接字,read()返回的請求數量比您要求的要少,因爲它無法返回仍在網絡中傳播的字節。

所以,如果你沒有得到你想要的所有東西,你需要檢查返回值read(),並再次調用它以獲得更多的數據,直到你擁有了所有的東西。

+0

感謝您的幫助! – testermaster 2014-11-03 03:11:24

相關問題