【问题标题】:Winsock2 - how to open a TCP socket that allows recv() with MSG_WAITALL?Winsock2 - 如何使用 MSG_WAITALL 打开允许 ​​recv() 的 TCP 套接字?
【发布时间】:2012-08-26 05:07:03
【问题描述】:

在这段代码中:

// 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();
}

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

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

但看起来我并没有从这个列表中做某事。为什么我的recv() 呼叫不起作用?

【问题讨论】:

    标签: winsock recv


    【解决方案1】:

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

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

    底层传输不支持 MSG_WAITALL

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

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

    【讨论】:

    • 我知道这是一个非常古老的答案,但它仍然不正确。 MSG_WAITALL 并不意味着底层协议需要支持任何类型的消息概念。 WinSock2 TCP 套接字支持 MSG_WAITALL。
    • @BluBb_mADe Microsoft 的默认传输提供程序不支持MSG_WAITALL,但 Winsock2 不仅限于该提供程序。其他第 3 方传输提供商可能支持MSG_WAITALL。这就是为什么引用的文件是这样写的——它是一份合同,而不是一份保证。 “IF 底层传输......”我已经更新了我的答案。
    • 我真的很想看到这个声称默认 TCP 不支持 MSG_WAITALL 的来源,因为我一直在使用socket(AF_INET, SOCK_STREAM, IPPROTO_TCP),这可以说是使用不支持 ipv6 的最默认方式与recv(..., MSG_WAITALL) 结合使用多年没有错误或问题。
    猜你喜欢
    • 2012-01-18
    • 1970-01-01
    • 2014-08-03
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2011-09-18
    相关资源
    最近更新 更多