问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/12214356/winsock2-how-to-open-a-tcp-socket-that-allows-recv-with-msg-waitall