I am trying to create a UDP client. When I try to send a message to the server I get a WSAEOPNOTSUPP
error message. But the subsequent recvfrom
call seems to work just fine. I haven't had a chance to test it with the server yet so I'm assuming the data will actually come back as expected. According to the documentation that error means
MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
Here is the code (sanitized for your protection)
WORD version = MAKEWORD(2, 2);
WSADATA data;
int error = 0;
if ((error = WSAStartup(version, &data)) != NO_ERROR)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: WSAStartup failed with error: {}", error));
return;
}
if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: System could not support WinSock 2.2."));
if (WSACleanup() == SOCKET_ERROR)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: Winsock cleanup error: {}", WSAGetLastError()));
}
return;
}
SOCKET s = INVALID_SOCKET;
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: Socket creation failed with error: {}", WSAGetLastError()));
if (WSACleanup() == SOCKET_ERROR)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: Winsock cleanup error: {}", WSAGetLastError()));
}
return;
}
int bytesRecv = 0;
ReceiveData receiveData;
struct sockaddr_in server_addr;
int server_addr_len = sizeof(server_addr);
memset((char *)&server_addr, 0, server_addr_len);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(2010);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
memset((char *)&receiveData, 0, sizeof(ReceiveData));
if (sendto(s, “hello”, strlen(“hello”), 0, (struct sockaddr *) &server_addr, server_addr_len) == SOCKET_ERROR)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: unable to send hello to server: {}", WSAGetLastError()));
}
while (bytesRecv != SOCKET_ERROR)
{
bytesRecv = recvfrom(s, (char*)&receiveData, sizeof(ReceiveData), 0, (struct sockaddr *) &server_addr, &server_addr_len);
if (bytesRecv > 0)
{
// parse the data
}
else
{
if (bytesRecv == SOCKET_ERROR)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: Reading data: {}", WSAGetLastError()));
}
}
}
if (closesocket(s) == SOCKET_ERROR)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: Unable to close socket: {}", WSAGetLastError()));
}
if (WSACleanup() == SOCKET_ERROR)
{
kzLogError(KZ_LOG_CATEGORY_GENERIC, ("Error: Winsock cleanup error: {}", WSAGetLastError()));
}