Welcome all.
I am trying to use Windows sockets to send and receive UDP packets (in C ++).
It worked well until three days ago when the program stopped behaving correctly.
To summarize the situation:
- When WSAPoll () is called on my socket, it always returns my socket, updated with EVERY RESCUE (which corresponds to all the events that I gave pollfd), even if the server is not running.
- When recvfrom () is called and the server starts, it does not return SOCKET_ERROR with error code 10054 (*).
- When recvfrom () is called and the server starts, it works correctly - it blocks until it receives something.
- The behavior is the same if I try to connect to a local host or a remote host.
(*) I investigated this error. In UDP, this means that there is a problem with ICMP. ("In the juice of a UDP datagram, this error indicates a previous send operation that resulted in an ICMP Port Unreachable message.").
I really call sendto () before recvfrom (), so the problem is not here.
I tried to set up my firewall to see if this had changed, but it is not. I also tried to suppress every network flowing through my computer. In this state, I managed to get the program to work for several minutes, but when I turned on the network, it stopped working again. I tried to repeat this process, but it will no longer work.
I tried compiling with both visual studio (2015) and MinGW.
I also tried on another computer (under Windows 7, I have Windows 8.1), to no avail.
Here is a simple test file that does not work on my computer.
#undef _WIN32_WINNT #define _WIN32_WINNT 0x501 #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <vector> #include <iostream> int main() { int clientSock; char buf[100]; int serverPort; /* Initializing WSA */ WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); /* I create my socket */ struct addrinfo specs; struct addrinfo *addr = new addrinfo; ZeroMemory(&specs, sizeof(specs)); specs.ai_family = AF_INET; specs.ai_socktype = SOCK_DGRAM; specs.ai_flags = 0; getaddrinfo("127.0.0.1", "2324", &specs, &addr); clientSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); /* I get the server address */ struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); serverAddr.sin_port = htons(2324); int len = sizeof(struct sockaddr); /* I'll poll & recvfrom on my socket */ std::vector<pollfd> fds; pollfd fd; fd.fd = clientSock; fd.events = POLLRDNORM; fd.revents = -1; fds.push_back(fd); while(1) { memset(buf,0,sizeof(buf)); printf("\nClient--->: "); gets(buf); /* It UDP, so it doesn't matter if there is someone to receive the packet */ sendto(clientSock, buf, strlen(buf), 0, (sockaddr*)&serverAddr ,len); memset(buf,0,sizeof(buf)); int ret; /* Always returns "1" */ if ((ret = WSAPoll(fds.data(), 1, 0)) > 0) { std::cout << ret; /* Always returns "-1" */ std::cout << recvfrom(clientSock,buf,sizeof(buf),0, (sockaddr*)&serverAddr,&len) << std::endl; printf("\n--->From the server: "); printf("%s",buf); } } closesocket(clientSock); WSACleanup(); return 0; }
Two questions:
- Why does WSAPoll () always return an updated socket, even if there was no interaction with it?
- Why is recvfrom () returning this error and how to fix it? I guess this is happening from my computer. I tried to allow ICMP through my firewall, but it didn’t change anything, maybe I did something wrong?
Edit: I fixed my main program (not shown here because it is too large), simply ignoring any "error 10054" I received. Now it works the same as on Unix.
However, this is not a solution (ignoring the error code ... meh), and if anyone knows why I get the "ICMP Port Unreachable" error message when calling sendto() , I would be happy to hear about it.