2016-05-16 218 views
0

我需要對在套接字程序中使用多個發送/接收進行說明。 我的客戶端程序如下所示(使用TCP SOCK_STREAM)。在套接字中發送多個發送/接收

send(sockfd,"Messgfromlient",15,0); 
    send(sockfd,"cli1",5,0); 
    send(sockfd,"cli2",5,0); 
    send(sockfd,"cli3",5,0); 
    send(sockfd,"cli4",5,0); 
    send(sockfd,"cli5",5,0); 

和服務器程序如下所示。

recv(newsockfd,buf,20,0); 
    printf("Buffer is %s\n",buf); 

當我執行上述程序,則輸出爲如下:

客戶端消息:Messgfromlient

相信BUF大小爲20,因此,只有一個緩衝器得到接收。 在服務器端添加一個recv。

char buf[20],buf[20]; 
    ------skipped------ 
    recv(newsockfd,buf,20,0); 
    recv(newsockfd,buf1,20,0); 
    printf("Client Msg :%s\n",buf); 
    printf("Client Msg :%s \n",buf1); 

輸出: 第一次試驗:

Client Msg :Messgfromlient 
    Client Msg :cli2 

第二個線索:

Client Msg :Messgfromlient 
    Client Msg :cli1 

正如我們可以看到,有在。OUPUTS一些矛盾, 從客戶端看起來一切郵件正在發送,但在服務器中,msg將基於buf大小接收,這裏儘管buf1的大小爲20,爲什麼'cli3''cli4''cli4'msgs沒有在bu上收到F1?有沒有特定的限制?請澄清一下。

由於事先 拉賈

+1

send()和recv()是什麼返回值?你不能忽視這一點。 –

+0

您正在發送5個字節和15個字節的緩衝區,但在接收時,您正在打印以第一個「NUL」字節(0x00)結尾的字符串。如果你保存了'recv()'調用的返回值並打印它們,這可能會有所幫助。 – TripeHound

+1

傳遞的'len'是允許的最大長度。 'recv'可以返回一個字符或者(在非阻塞系統中)a -'1'。您的「問題」屬於進程調度:它取決於在上下文切換之前執行的代碼點以及內核已經分離的內容。 – LPs

回答

3

TCP是一個字節流的協議,因此它不知道的消息。您總共發送25字節,而另一方的每個recv將讀取這些字節的一些。你可以得到20,你可能會得到1然後19在接下來的閱讀,你可能會得到5然後4然後11然後5.大小參數recv是最大讀取的數量。

您需要進行循環,直到您自己閱讀完整消息,並且也明白您可能會在同一收到的消息中收到多個「發送」消息。

3

服務器程序看起來像下面。

recv(newsockfd,buf,20,0); 
printf("Buffer is %s\n",buf); 

這已經是錯誤的。它應該是:

int count = recv(newsockfd,buf,20,0); 
if (count == -1) 
{ 
    perror("recv"); // please improve this message 
    close(newsocketfd); 
} 
else if (count == 0) 
{ 
    // peer has closed the connection 
    close(newsockfd); 
} 
else 
{ 
    printf("Buffer is %.*s\n",count,buf); 
} 

這應該給你足夠的暗示的......

2

你有2個問題:

當你顯示結果,你要停在第一個空字節,它始終是「Messgfromlient」之後。可能有更多的文字已經收到,但你沒有顯示它。

第二個問題是TCP連接是一個流。您可能一次接收所有數據,您可能只收到第一個字節。你不知道哪一個是它,也不能預測它。您需要處理應用程序中的不完整讀取,並且必須處理重試。

但是,您可以更有可能將所有數據發送到一個數據包而不是6個。查看TCP_CORK選項。