2016-09-29 184 views
-1

這是一個比問題更多的確認請求,所以我會保持簡短。 (我遠離我的電腦,所以不能簡單地實施這個解決方案來測試)。C++套接字緩衝區大小

我正在編寫一個程序,將通過攝像頭拍攝的圖像文件(以及元數據)從raspberryPi發送到我的電腦。

我已經計算出圖像大概在130kb左右,包頭是12b,相關的元數據是24b。儘管未來我可能會增加圖像尺寸,但一旦我有了一個可用的原型。

目前我無法成功檢索到整個數據包,因爲在將它發送到PC後,我只能收到約64kb的緩衝區。

我假定這是因爲無論是什麼原因宣佈像一個套接字的默認緩衝區大小爲:

SOCKET sock = socket(PF_INET, SOCK_STREAM, 0); 

爲64KB(請可能有人澄清這一點,如果你「在知道」是)

所以 - 要解決這個問題,我打算通過setsockopt(x ..)命令將套接字大小增加到1024kb。

請有人確認我的問題診斷,並提出解決方案是否正確?

我問這個問題,因爲我現在離開我的電腦,無法嘗試,直到我回到家。

+0

我在思考自己的另一種選擇是手動分段數據包。不過,我懷疑,這會引入更多的錯誤潛力,並會增加整體數據包大小/計算時間,因爲我需要爲每個單獨的段發送和讀取標題。 –

+0

倫敦是一塊磚頭,你沒有收到所有數據的原因是你認爲'recv()'填充你的緩衝區而不是循環。文檔中沒有任何內容支持這一假設。 – EJP

+0

感謝您的迴應,並非100%確定我關注您,但要澄清:我知道傳入數據的大小,因爲它存儲在標題中,並且將其解壓縮,讀取,並分配適當大小的緩衝區以接收剩餘的數據。 因此,在進一步的解釋: >找頭,與數據包大小 >創建正確的大小 的緩衝>運行的recv填充緩衝區並記字節收到 >在頭接收到的校驗字節對數據大小 –

回答

0

這很可能與套接字緩衝區無關,但事實上recv()send()不必接收和發送所有你想要的數據。檢查這些函數調用的返回值,它表示實際發送和接收的字節數。

應對「短」最好的辦法讀/寫是把它們放在一個循環,像這樣:

char *buf; // pointer to your data 
size_t len; // length of your data 
int fd;  // the socket filedescriptor 

size_t offset = 0; 
ssize_t result; 
while (offset < len) { 
    result = send(fd, buf + offset, len - offset, 0); 
    if (result < 0) { 
    // Deal with errors here 
    } 
    offset += result; 
} 

使用類似的結構用於接收數據。請注意,一種可能的錯誤情況是函數調用被中斷(errno = EAGAINEWOULDBLOCK),在這種情況下,您應該重試發送命令,在所有其他情況下,您應該退出循環。

+0

謝謝@ G.Sliepen。所以,我看到你正在發送一個循環,因此建議(請糾正我,如果沒有)在接收端,應該使用循環recv。 - 什麼是防止意外收回的數據,比如從不相關的程序發送到端口的附帶數據包?我能想到的唯一辦法就是把一個標題放在裏面,裏面有一個'20部分10'類型的ID。這似乎沒有創造更多的問題? - 我想我的主要問題是,我不能只增加send/recv使用的內部系統緩衝區的大小嗎?即setsockopt ... –

+0

是的,你應該在接收端使用接收環路。 TCP套接字(我假設你正在使用的是)總是提供來自單個連接的有序數據流。因此,您將不會收到來自不相關網絡連接的虛假數據,並且您將看到所有數據以與發送時相同的順序進入。 –