Problem mit UDP Verbindung
-
Hallo zusammen,
ich habe ein Problem mit einer UDP-Verbindung (C++) zwischen der Flugsimulationssoftware x-Plane und einer von mir geschriebene Moving-Map Anwendung. Wenn ich zuerst X-Plane starte und anschließend die Moving-Map ist alles in Ordnung. Anders herum funktioniert es jedoch nicht. Das wäre zwar nicht so schlimm, aber leider wird bei jedem Laden eines neuen Flugplatzes, etc. die UDP Verbindung seitens X-Plane gekillt (denke ich zumindest). Damit funktioniert nach jedem Ladevorgang das Programm nicht mehr. Die einzige mir bekannte Lösung wäre, den Timeout der select-Funktion entsprechend hochzusetzen, aber dann müsste sichergestellt sein, dass jeder Ladevorgang auch tatsächlich innerhalb dieser Zeit fertiggestellt ist (was aber natürlich auch Hardwareabhängig ist). Gibt es zu dem Problem eine elegante Lösung?
Hier der Ausschnitt aus dem UDP-Teil des Programms:
XData::XData() { uint16_t wVersion = MAKEWORD(2, 2); uint32_t error = 0; error = WSAStartup(wVersion, &wsaData); if (0 != error) { std::cout << "WSAStartup failed with error " << error << std::endl; std::cout << GetLastError() << std::endl; } udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (INVALID_SOCKET == udpSocket) { std::cout << "Socket creation failed with error "; std::cout << GetLastError() << std::endl; } address.sin_family = AF_INET; address.sin_port = htons(port); address.sin_addr.s_addr = INADDR_ANY; if (SOCKET_ERROR == bind(udpSocket, reinterpret_cast<SOCKADDR*>(&address), sizeof(address))) { std::cout << "Error in binding with error " << GetLastError() << std::endl; } FD_SET(udpSocket, &fdSet); update(); } XData::~XData() { FD_CLR(udpSocket, &fdSet); closesocket(udpSocket); WSACleanup(); } bool XData::update() { timeval timeval = {1, 0}; if (select(0, &fdSet, nullptr, nullptr, &timeval) > 0) { received = recv(udpSocket, buffer, sizeof(buffer), 0); if (0 == received) { std::cout << "No data received\n"; return false; } // Control of the message type if (!(buffer[0] == 'D' && buffer[1] == 'A' && buffer[2] == 'T' && buffer[3] == 'A')) { std::cout << "No 'DATA' header!\n"; return false; } convert(); } //Socket Errors? int error = WSAGetLastError(); if(error != 0) { // std::cout << "Socket Error: " << error << std::endl; } return true; }
-
Was mir aufgefallen ist das FD_ZERO(...) vor FD_SET fehlt.
-
Ah danke. Dank dir hab ich jetzt herausgefunden, dass man FD_ZERO und FD_SET periodisch abfragen muss. Select löscht ja ungültige Sockets aus der Liste. Jetzt funktioniert alles wie es soll.