2016-09-29 178 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套接字(我假设你正在使用的是)总是提供来自单个连接的有序数据流。因此,您将不会收到来自不相关网络连接的虚假数据,并且您将看到所有数据以与发送时相同的顺序进入。 –