2009-07-20 91 views
1

我正在嘗試使用Linux使用TCP套接字傳輸圖像。我已經多次使用該代碼來傳輸少量數據,但只要我嘗試傳輸圖像,它只轉移了前三分之一。 Linux中有沒有可能的最大緩衝區大小爲tcp套接字?如果是這樣,我該如何增加它?有沒有一個函數以編程方式執行?在Linux中使用TCP套接字傳輸圖像

+0

它獲得了多少數據? – Javier 2009-07-20 21:35:48

+1

我發送800x600x3(1440000字節),我只收到65536字節 – DHamrick 2009-07-20 21:42:09

+0

你有一些代碼嗎?請記住,TCP是一個流,而不是面向消息的。 一次寫入調用可能需要幾次讀取調用才能讀取。或者幾次寫入調用可能只需要一次寫入調用即可接收。記住要檢查write()的返回值,你有責任編寫所有的數據,write()調用可能只是發送部分數據。 – nos 2009-07-20 22:01:11

回答

1

TCP發送的片數據,所以你不能保證有一個讀得到它一下子(儘管它保證留在命令你把它)。你基本上必須多次閱讀,直到獲得所有數據。它也不知道你在接收端發送了多少數據。通常情況下,您首先發送一個固定大小的「長度」字段(例如總是8個字節),以便知道有多少數據。然後你繼續閱讀並建立一個緩衝區,直到你得到那麼多字節。

那麼發送方會是這個樣子(僞)

int imageLength; 
char *imageData; 

// set imageLength and imageData 

send(&imageLength, sizeof(int)); 
send(imageData, imageLength); 

和接收器應該是這樣的(僞)

int imageLength; 
char *imageData; 

guaranteed_read(&imageLength, sizeof(int)); 
imageData = new char[imageLength]; 
guaranteed_read(imageData, imageLength); 

void guaranteed_read(char* destBuf, int length) 
{ 
    int totalRead=0, numRead; 
    while(totalRead < length) 
    { 
     int remaining = length - totalRead; 
     numRead = read(&destBuf[totalRead], remaining); 
     if(numRead > 0) 
     { 
      totalRead += numRead; 
     } 
     else 
     { 
      // error reading from socket 
     } 
    } 
} 

很顯然,我離開了實際的socket描述符,你需要爲所有這些添加了很多錯誤檢查。這並不意味着完整,更多的是展示這個想法。

3

我想,當你從套接字讀取時,問題出現在接收端。 TCP是基於流的協議,不知道數據包或消息邊界。

這意味着當您讀取時,您可能獲得的字節數少於您的請求。例如,如果您的圖像爲128k,則您的首次閱讀只能獲得24k,要求您再次閱讀以獲取其餘數據。這是一個圖像的事實是無關緊要的。數據是數據。

例如:

int read_image(int sock, int size, unsigned char *buf) { 
    int bytes_read = 0, len = 0; 
    while (bytes_read < size && ((len = recv(sock, buf + bytes_read,size-bytes_read, 0)) > 0)) { 
     bytes_read += len; 
    } 
    if (len == 0 || len < 0) doerror(); 
    return bytes_read; 
} 
0

1個單個IP分組的最大大小爲65535,這是非常接近你打次數。我懷疑這是巧合。