Winsock2 - how to open a TCP socket that allows re

2019-08-06 04:10发布

In this code:

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

(note the MSG_WAITALL flag in recv()) everything works fine, expect for recv(). WSAGetLastError() returns WSAEOPNOTSUPP.
MSDN states that

Note that if the underlying transport does not support MSG_WAITALL, or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP. Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP. This flag is not supported on datagram sockets or message-oriented sockets.

But it doesn't look like I'm doing something from this list. Why my recv() call doesn't work?

标签: winsock recv
1条回答
霸刀☆藐视天下
2楼-- · 2019-08-06 05:03

it doesn't look like I'm doing something from this list.

Yes, you are - the very first item on the list:

the underlying transport does not support MSG_WAITALL

TCP does not support MSG_WAITALL. TCP is a byte stream, it does not deal in messages. recv() is not limited to just TCP, it supports any transport that the underlying provider supports - TCP, UDP, IPX, ICMP, RAW, etc.

If you want recv() to wait until all of the requested TCP data has been received, you have to set the socket to blocking mode (its default mode) and then set the flags parameter of recv() to 0.

查看更多
登录 后发表回答