UDP recv在接收超过8字节时失败 < P>我想通过C++无阻塞的ReV接收数据,所有的工作都能达到8字节的有效载荷,但是当我尝试接收9字节或更多时,ReCV返回- 1,而ErrNO是0。

UDP recv在接收超过8字节时失败 < P>我想通过C++无阻塞的ReV接收数据,所有的工作都能达到8字节的有效载荷,但是当我尝试接收9字节或更多时,ReCV返回- 1,而ErrNO是0。,c++,udp,recv,C++,Udp,Recv,下面是我代码的相关部分。检查init fcns的返回值并确定,只需将其保留以缩短代码段 初始化代码: WSADATA w; HANDLE soc, sem; SOCKADDR_IN addr; err = WSAStartup(0x0202, &w); soc = socket(AF_INET, SOCK_DGRAM, 0); memset((void *)&addr, '\0', sizeof(addr)); addr.sin_family = AF_INET; addr.s

下面是我代码的相关部分。检查init fcns的返回值并确定,只需将其保留以缩短代码段

初始化代码:

WSADATA w;
HANDLE soc, sem;
SOCKADDR_IN addr;

err = WSAStartup(0x0202, &w);
soc = socket(AF_INET, SOCK_DGRAM, 0);
memset((void *)&addr, '\0', sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(50001);
addr.sin_addr.s_addr = ADDR_ANY;

sem = CreateEvent(nullptr, false, false, nullptr);
WSAEventSelect(soc, sem, FD_READ);
接收器线程:

char buf[10000];
int bytes_read = 0;

while (true){
    WSAWaitForMultipleEvents(1, enqueue_sem, false, WSA_INFINITE, false);

    bytes_read = recv(soc, buf, sizeof(buf), 0);
    cout << bytes_read << ":" << strerror(errno) << endl;
    cout << buf << endl;
}
charbuf[10000];
int bytes_read=0;
while(true){
WSAWaitForMultipleEvents(1,排队,false,WSA\u无限,false);
字节读取=recv(soc,buf,sizeof(buf),0);

cout我的猜测是,您的代码看起来与您向我们展示的代码略有不同:

 char global_buf[10000];
 char *buf = global_buf;
 recv(soc,buf,sizeof(buf),0);

在这种情况下,
sizeof(buf)
不是10000,而是8(64位平台上指针的大小),这就解释了为什么你只能接收8个字节。

8个字节对我来说听起来像是一个64位的变量。可能你使用的是一个变量作为缓冲区,而不是一个地址,反之亦然。扩展@Dwayne的评论:我打赌在你的真实代码
buf
中不是一个
char
数组,而是一个
char*
指针。
 sizeof(buf)
是指针的大小,而不是它所指向的缓冲区的大小。听起来很可疑,但即使我的buf只有8个字节长,recv也应该将所有数据复制到sizeof(buf)并毫无错误地丢弃剩余部分。对吗?还有什么想法吗?顺便说一句:buf被定义为char buf[10000];
recv
将数据报仅部分接收的事实报告为错误。具体而言,
WSAEMSGSIZE
:“消息太大,无法放入指定的缓冲区,因此被截断。”有没有办法找到recv返回-1的原因?谢谢您和@Dwayne的提示,这确实是问题所在,但我还是不太满意。有没有可能从recv获得比-1更精确的错误代码?请参阅。它说,您可以通过调用
WSAGetLastError
获得更详细的错误。在您的例子中,this可能会导致
WSAEMSGSIZE
:“消息太大,无法放入指定的缓冲区,因此被截断”。