Hey everyone, I'm having some trouble using WaitForMultipleObjects to wait for incoming connections (which I would later accept()).
My code simply uses one thread to start listening, and then uses the main thread to try to connect to it.
Code:// Main Thread int main() { WSAData wsaData; if (WSAStartup(MAKEWORD(1, 1), &wsaData)) assert(false); pthread_t mynewthread; pthread_create(&mynewthread, NULL, threadMain, NULL); // Wait for the listener thread to be ready Sleep(2000); // Now try to connect to the thread via tcp SOCKET socket = ::socket(AF_INET, SOCK_STREAM, 0); struct hostent *hp = gethostbyname("127.0.0.1"); assert(hp); struct sockaddr_in server; server.sin_family = AF_INET; memcpy(&server.sin_addr.s_addr, hp->h_addr, hp->h_length); server.sin_port = htons(1337); if (::connect(socket, (const sockaddr *)&server, sizeof(server))) { std::cout << GetLastErrorMessage(GetLastError()) << std::endl; assert(false); } cout << "connected successfully!" << endl; }Any idea why WaitForMultipleObjects isnt waiting for connections like listen() would?Code:// Listener Thread HANDLE getEventAndEnableNonblockingMode(SOCKET socket) { HANDLE socketEventHandle = WSACreateEvent(); WSAEventSelect(socket, socketEventHandle, FD_ACCEPT | FD_READ | FD_CLOSE); return socketEventHandle; } void closeEventAndDisableNonblockingMode(SOCKET socket, HANDLE socketEventHandle) { // We need to close it here because having an event // open puts the socket in non-blocking mode. we need it to be in blocking mode for // things like accept(). WSACloseEvent(socketEventHandle); WSAEventSelect(socket, NULL, 0); // Now we make it blocking. unsigned long resultBuffer = 0; unsigned long resultBufferBytesWritten = 0; unsigned long newNonblockingEnabled = 0; int error = WSAIoctl(socket, FIONBIO, &newNonblockingEnabled, sizeof(unsigned long), &resultBuffer, sizeof(resultBuffer), &resultBufferBytesWritten, NULL, NULL); assert(error == 0); } void *threadMain(void *args) { SOCKET listenSocket = ::socket(AF_INET, SOCK_STREAM, 0); assert(listenSocket >= 0); struct sockaddr_in name; name.sin_family = AF_INET; name.sin_addr.s_addr = htonl(INADDR_ANY); name.sin_port = htons(1337); int nameStructLength = sizeof(name); if (bind(listenSocket, (struct sockaddr *)&name, nameStructLength)) { int error = GetLastError(); std::cout << "Error in connection listener: " << GetLastErrorMessage(error) << std::endl; } HANDLE socketEventHandle = getEventAndEnableNonblockingMode(listenSocket); HANDLE events[1] = { socketEventHandle }; DWORD result = WaitForMultipleObjects(1, events, false, INFINITE); closeEventAndDisableNonblockingMode(listenSocket, socketEventHandle); if (result == WAIT_OBJECT_0) { } else { assert(false); } cout << "wfmo returned!" << endl; return NULL; }
Thanks!
PS. I need to use WaitForMultipleObjects because soon I will be waiting on more than just the socket, I'll need to respond to a number of other events as well.



LinkBack URL
About LinkBacks



