![](/img/trans.png)
[英]How to recv and send data on UDP socket on single client simultaneously
[英]Read all data during single recv() method from a socket
我正在尝试使用套接字编程连续读取数据。 我使用 recv() 接收套接字上的数据。 我将它存储在缓冲区中。 recv() 返回读取的字节数。 以下是片段:
while (true) {
try {
char buff[2048];
int bytes = recv(sockfd, buff, 2048, 0);
buff[bytes] = '\0';
cout << strlen(buff) << endl;
cout << bytes << endl;
cout << "-------" << endl;
} catch (const char *e) {
}
}
以下是output的代码:
1
1204
-------
1
1390
-------
1
25
-------
1
1204
-------
通过 recv() 方法接收到的字节数是正确的,但我无法读取确切的数据数。 如何读取在单个 recv() 方法期间捕获的所有数据?
您需要像文档中那样将正确的标志传递给 recv 。 基于: https://man7.org/linux/man-pages/man2/recv.2.html有标志 MSG_WAITALL (因为 ZEDC9F0A5A5D57797BF368E37326474 做什么)
调用看起来像:
int bytes = recv(sockfd, buff, 2048, MSG_WAITALL);
除非您确定只收到文本,否则通过 strlen 检查接收字节的长度是不好的。
您可以创建一个std::string_view
指向读取的数据。
while (true) {
char buff[2048];
int bytes = recv(sockfd, buff, 2048, 0);
if (bytes >= 0) {
std::string_view read { buff, bytes };
std::cout << read << std::endl;
std::cout << "-------" << std::endl;
} // else?
}
function strlen
会将buff
的内容视为以 null 结尾的字符串并返回该字符串的长度。
在行
buff[bytes] = '\0';
您在数据末尾写了一个 null 终止字符。 这样,您就确保了数据以空值结尾。
但是, recv
读取的字节可能包含值为0
的字节。 function strlen
将无法区分这样的字节和实际的终止 null 字符。 它将简单地返回值为0
的第一个字节的 position 的索引。
这就是为什么表达式strlen(buff)
与数据的实际长度不对应的原因。
因此,您不应在二进制数据上使用 function strlen
。 function 仅用于文本数据,它不能包含值为0
的字符,除了标记字符串的结尾。
不应使用strlen
来确定数据的长度,而应仅使用recv
返回的值(已存储在变量bytes
中)。 只要记住这个值,就永远知道长度,所以不需要用终止符 null 来标记数据的结尾。
假设recv
返回正值(负数表示失败),你会找到数组buff
中的所有数据, recv
的返回值将指定数据的长度。 例如,如果您想打印在对recv
的 function 调用中收到的所有数据,则可以在recv
function 调用之后立即编写以下内容:
for ( int i = 0; i < bytes; i++ )
cout << hex << setw(2) << setfill( '0' ) << static_cast<int>(buff[i]) << ' ';
请注意,您必须在程序开头添加#include <iomanip>
才能使该行生效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.