1

在这段代码中:

// error checking is omitted

// init Winsock2
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

// connect to server
struct addrinfo *res = NULL, *ptr = NULL, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

getaddrinfo(server_ip, "9999", &hints, &res);
SOCKET client_socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

connect(client_socket, res->ai_addr, (int)res->ai_addrlen);

freeaddrinfo(res);
res = NULL;

// read the data
unsinged int size1;
if (recv(client_socket, (char*)&size1, sizeof(int), MSG_WAITALL) == SOCKET_ERROR)
{
    return WSAGetLastError();
}

(注意 中的MSG_WAITALL标志recv())一切正常,期待recv(). WSAGetLastError()返回WSAEOPNOTSUPP
MSDN 指出

请注意,如果底层传输不支持 MSG_WAITALL,或者如果套接字处于非阻塞模式,则此调用将失败并显示 WSAEOPNOTSUPP。此外,如果 MSG_WAITALL 与 MSG_OOB、MSG_PEEK 或 MSG_PARTIAL 一起指定,则此调用将失败并显示 WSAEOPNOTSUPP。数据报套接字或面向消息的套接字不支持此标志。

但看起来我并没有从这个列表中做一些事情。为什么我的recv()电话打不通?

4

1 回答 1

1

看起来我并没有从这个列表中做某事。

是的,您是 - 列表中的第一项:

底层传输不支持 MSG_WAITALL

Microsoft 的默认 TCP 传输提供程序不支持MSG_WAITALL. recv(),以及一般的 Winsock,不仅限于 Microsoft 的 TCP 提供程序。它支持第 3 方提供商,以及提供商支持的任何传输协议 - TCP、UDP、IPX、ICMP、RAW 等。

在使用微软的 TCP 时,如果要recv()等到所有请求的 TCP 数据都接收完毕,则必须将套接字设置为阻塞模式(其默认模式),然后将flags参数设置recv()为 0。但即使这样也不能保证,recv()可以返回比请求更少的字节,因此您应该准备好recv()循环调用,直到实际接收到所有预期的字节。

于 2012-08-31T18:35:56.573 回答