2010-11-15 63 views
2

我有幾個涉及以下代碼的問題:插座數據長度問題

char buffer[256]; 
memset(buffer,0,256); 

read(socket_fd,buffer,255); 

的問題:

  1. 我爲什麼讀不255 256?
  2. 假設我想從客戶端向服務器發送「酷」這個詞。我應該在「客戶端」中寫入多少字節,並且我應該在服務器中讀取多少字節?

我真的很困惑。

+3

你不會像我一樣困惑一半 – 2010-11-15 17:19:51

回答

8

你已經有了很好的答案,但我認爲我們應該解釋一個概念。

當你通過數據流發送數據時(也就是說,從一端寫入大量字節的東西,這些字節可以在另一端以相同的順序讀取),你幾乎總是想知道何時停止讀。如果您發送多件事情,這是強制性的:第一條消息何時停止,第二條消息何時開始?在流中,事情混淆了。

那麼,我們如何分隔消息呢?有三種簡單的方法(和許多其他不是那麼簡單的,當然):

1固定長度的消息: 如果你事先知道每一個消息是,比方說,10字節長,那麼你就不要沒有問題。你只讀了10個字節,而第11個字節將成爲另一個消息的一部分。這非常簡單,但也非常僵硬。

2個勘定字符或字符串: 如果您發送的人類可讀的文本,你可能會劃你的消息,你在你的char*的分隔字符串以同樣的方式:把一個0字符結尾。這樣,當您讀取0時,您知道該消息已結束,並且流中的所有剩餘數據都屬於另一個消息。

這對ascii文本是可以的,但是當涉及到任意數據時,它也有點兒僵化:有一個字符或一系列字符,您的郵件不能包含(或者您的程序會對於哪裏一條消息結束)。

3消息標題: 這是任意長度,任意內容消息的最佳方法。在發送任何實際的消息數據之前,發送一個固定長度的頭文件(或者使用技巧nr 2來標記頭文件的末尾),指定關於消息的元數據。例如,它的長度。

假如你想發送消息'酷',如你所說。那麼,首先發送一個包含'4'(即消息長度)的字節(或2字節短或4字節整數,或其他),並在另一端接收它。您知道在任何消息到達之前,您必須讀取1個字節(或2個,或4個,或其他),因此將其存儲在某個地方,然後讀取剩餘的指定字節。

很簡單的例子:

struct mheader { 
    int length; 
}; 

(...) 
struct mheader in_h; 
read(fd, &in_h, sizeof(struct mheader); 

if (in_h.length > 0) 
    read(fd, buffer, in_h.length) 

希望它能幫助。祝你好運!

+0

非常好的解釋。謝謝! – 2010-11-15 19:43:22

3
  1. 這樣緩衝區就保留了NUL,作爲對字符串溢出的額外保險。讀256將允許它被覆蓋。

  2. 你會寫五個字節。要麼寫入"Cool\0",要麼寫入4(長度),然後寫入「酷」中的4個字符。閱讀所有內容,然後確定長度。

3

你看看從read()返回的值;它會告訴你讀了多少字節。

您可以使用在要寫入相同數據時讀取的字節數。

除非您確實希望能夠在最後放置NUL,否則您不必在讀取中使用255,但由於您知道有多少字節被讀取,因此無論如何您都不會超出這個範圍。所以,255是程序員防範粗心的保險政策。

memset()同樣也是防止程序員粗心大意的保險政策 - 除非您想屏蔽以前的敏感數據,否則這並不是真的必要。