Passing Socket to Thread C

c, c++, multithreading, sockets

Solution

The main thread closes the socket immediately after starting the other thread. Therefore the thread no longer has a valid socket handle.

Problem

I'm trying to make a network system using UDP. I've managed to get it working, but now I want to put the listening part in a separate thread so I can continue with the program without having to wait for messages (it's going to be used for a game). The problem is that when I pass the socket to the new thread and use it for listening it doesn't work and just receives random input constantly. When I use the exact same code in the method where I initialize the socket, everything works fine. This works: ``` bool serverUDP() { WSADATA w; SOCKET sd; struct sockaddr_in server, client; char buffer[DEFAULT_BUFLEN]; int bytes_received; int client_length; /* Open windows connection */ if (WSAStartup(MAKEWORD(2,2)/*0x0101*/, &w) != 0) { fprintf(stderr, "Could not open Windows connection.\n"); return false; } /* Open a datagram socket */ sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd == INVALID_SOCKET) { fprintf(stderr, "Could not create socket.\n"); WSACleanup(); return false; } /* Clear out server struct */ memset((void *)&server, '\0', sizeof(struct sockaddr_in)); /* Set family and port */ server.sin_family = AF_INET; server.sin_port = htons(atoi(DEFAULT_PORT)); server.sin_addr.S_un.S_un_b.s_b1 = 127; server.sin_addr.S_un.S_un_b.s_b2 = 0; server.sin_addr.S_un.S_un_b.s_b3 = 0; server.sin_addr.S_un.S_un_b.s_b4 = 1; /* Bind address to socket */ if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1) { fprintf(stderr, "Could not bind name to socket.\n"); closesocket(sd); WSACleanup(); return false; } client_length = (int)sizeof(struct sockaddr_in); /* Receive bytes from client */ while (true) { bytes_received = recvfrom(sd, buffer, DEFAULT_BUFLEN, 0, (struct sockaddr *)&client, &client_length); fprintf(stderr,"received: %s\n", buffer); } closesocket(sd); WSACleanup(); return true; } ``` This doesn't: ``` bool serverUDP() { WSADATA w; SOCKET sd; struct sockaddr_in server, client; char buffer[DEFAULT_BUFLEN]; int bytes_received; int client_length; /* Open windows connection */ if (WSAStartup(MAKEWORD(2,2)/*0x0101*/, &w) != 0) { fprintf(stderr, "Could not open Windows connection.\n"); return false; } /* Open a datagram socket */ sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd == INVALID_SOCKET) { fprintf(stderr, "Could not create socket.\n"); WSACleanup(); return false; } /* Clear out server struct */ memset((void *)&server, '\0', sizeof(struct sockaddr_in)); /* Set family and port */ server.sin_family = AF_INET; server.sin_port = htons(atoi(DEFAULT_PORT)); server.sin_addr.S_un.S_un_b.s_b1 = 127; server.sin_addr.S_un.S_un_b.s_b2 = 0; server.sin_addr.S_un.S_un_b.s_b3 = 0; server.sin_addr.S_un.S_un_b.s_b4 = 1; /* Bind address to socket */ if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1) { fprintf(stderr, "Could not bind name to socket.\n"); closesocket(sd); WSACleanup(); return false; } _beginthread((void(*)(void*))receiveThread,0,(void *)sd); closesocket(sd); WSACleanup(); return true; } void receiveThread(SOCKET sd) { struct sockaddr_in client, server; char buffer[DEFAULT_BUFLEN]; int bytes_received; int client_length; client_length = (int)sizeof(struct sockaddr_in); while (true) { bytes_received = recvfrom(sd, buffer, DEFAULT_BUFLEN, 0, (struct sockaddr *)&client, &client_length); fprintf(stderr,"received: %s\n", buffer); } } ``` The second piece of code just spams random input, as though it's constantly receiving some weird message. The, first piece of code waits for a message and continues when it gets one (I've got a client part too). Thanks for your help! Cheers, Maxim Schoemaker

Original source