我正在为文件传输应用程序开发服务器。文件从Android手机发送到我的服务器。
当文件很小时,它可以顺利运行。但是当文件大小很大(> 2MB)时,服务器不会收到整个数据包。
int recv(
_In_ SOCKET s,
_Out_ char *buf,
_In_ int len,
_In_ int flags
);
len
函数中recv
的值最初设置为20000
,当我将其更改为8000
时,它开始工作。
令人惊讶的是,这只发生在Release mode in Visual Studio.
我使用wireshark从我的移动设备捕获日志。当服务器在调试模式下运行时,手机会发送所有数据,但当服务器在释放模式下运行时,手机不会发送整个数据。 (这是当len的值设置为20000
)时。
但是,如果我通过基于PC的客户端发送大文件(客户端与服务器在同一台机器上),len
的值可以保持在20000.
有没有人遇到过这样的问题?这种行为的原因是什么?
注意:我正在使用Visual Studio在Windows上进行开发。
答案 0 :(得分:4)
len
的{{1}}参数指定要读取的最大字节数。无法保证recv
在完全读取此金额之前会阻止;它可能在读取任何较小数量的字节后返回。读取的实际数据量在返回值中记录。
如果您想要读取一定数量的字节
,则需要自己反复调用recv
recv
答案 1 :(得分:1)
recv 或发送的 len 参数都不是一个确切的值,它只是对如何提示你可以最大限度地存储的数据(用于recv)或你想发送多少数据,每个函数返回一个错误或处理的字节数可能比你要求的更少,忽略这种情况将由于服务器没有完全发送它或者客户端没有收到正确的数量,因此导致随机的错误。
最安全的方法是每次发送一个标题,这样可以确保您知道要接收的数据量,在客户端上您希望结构然后是数据。因为在这种情况下,您确切地知道要发送/接收的数据量,您可以依赖它并继续调用函数,直到它们失败或最终执行您想要的操作(发送所有数据或收集所有数据)。
也永远不要尝试一次发送太大的块,因为它将填满winsock内部缓冲区,因此函数将返回这是合理的,因为它无法处理您的请求,因为它需要先发送数据或没有还有更多空间可以获得更多。