Mehrere Threads - Anzahl: Unbekannt
-
So, ich grab den Thread nochmal aus, da ich keine Lust habe nen neuen aufzumachen.
Handelt sich immer noch um das selbe Projekt, doch jetzt sind es nur knapp 7 IPs in der Text Datei, somit hatte ich vor CreateThread zu verwenden und 7 Threads zu starten.
Das ganze funktioniert insofern das wirklich 7 Threads gestartet werden, doch immer nur der letzte Thread aktiv über send() Daten zum Server schickt(Habe es mit WPE Pro gesnifft!). Das Programm scchickt also nur immer zu der letzten IP die in der Textdatei steht das packet. Die ersten 6 Threads scheinen nicht zu laufen.
Hier kurzer Ausschnitt von den wichtigen Sachen:typedef struct MyData { char *cGlobalIP; char *cGlobalPort; }MYDATA, *PMYDATA; int main(int argc, char *argv[]) { PMYDATA pDataArray[7]; DWORD dwThreadIdArray[7]; HANDLE hThreadArray[7]; char cServer[MAX_PATH]; fstream fServer; fServer.open(argv[1], ios::in); while(!fServer.eof()) { //String teilen fServer.getline(cServer, sizeof(cServer)); /* ... Hier wird nur IP vom Port getrennt. cIP ist die IP und cPort der Port. :) */ //Thread erstellen int i = 0; pDataArray[i] = (PMYDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA)); pDataArray[i]->cGlobalIP = cIP; pDataArray[i]->cGlobalPort = cPort; hThreadArray[i] = CreateThread(NULL, 0, Server, pDataArray[i], 0, &dwThreadIdArray[i]); i++; } fServer.close(); cout << GetLastError() << endl; system("PAUSE"); //Threads beenden und Speicher freigeben return 0; } DWORD WINAPI Server(LPVOID lpParam) { PMYDATA pDataArray = (PMYDATA)lpParam; int nResult; WSADATA wsaData; SOCKET ConnectSocket; struct sockaddr_in clientService; nResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(nResult != NO_ERROR) { return 0; } ConnectSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(ConnectSocket == INVALID_SOCKET) { return 0; } clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr(pDataArray->cGlobalIP); clientService.sin_port = htons(atoi(pDataArray->cGlobalPort)); nResult = connect(ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService)); if(nResult == SOCKET_ERROR) { return 0; } while(1) { //blablabla :D } return 1; }
-
Auf die Schnelle:
C und C++ mischen == hässlich (true)
WSAStartup nur 1x aufrufen
struct initialisieren: sockaddr_in clientService = { };
besser kein connect() bei UDP, sondern einfach nur sendto/recvfrom
sämtliche rückgabewerte prüfen und checken was falsch läuft
-
Danke schonmal für deine Antwort, ich habe versucht all deine Tipps zu befolgen, doch das Problem besteht weiter hin.
Soweit bin ich schon... Doch es wird tatsächlich nur der letzte Server abgefragt, somit frag ich mich was die anderen Threads machen?typedef struct MyData { char *cGlobalIP; char *cGlobalPort; }MYDATA, *PMYDATA; int main(int argc, char *argv[]) { int nResult; WSADATA wsaData; nResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(nResult != NO_ERROR) { cout << "WSAStartup: " << WSAGetLastError() << endl; system("PAUSE"); return 0; } PMYDATA pDataArray[7]; DWORD dwThreadIdArray[7]; HANDLE hThreadArray[7]; char cServer[MAX_PATH]; fstream fServer; fServer.open(argv[1], ios::in); while(!fServer.eof()) { //String teilen fServer.getline(cServer, sizeof(cServer)); /* ... Hier wird nur IP vom Port getrennt. cIP ist die IP und cPort der Port. :) */ //Thread erstellen int i = 0; pDataArray[i] = (PMYDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA)); pDataArray[i]->cGlobalIP = cIP; pDataArray[i]->cGlobalPort = cPort; hThreadArray[i] = CreateThread(NULL, 0, Server, pDataArray[i], 0, &dwThreadIdArray[i]); i++; } fServer.close(); cout << GetLastError() << endl; system("PAUSE"); //Threads beenden und Speicher freigeben return 0; } DWORD WINAPI Server(LPVOID lpParam) { PMYDATA pDataArray = (PMYDATA)lpParam; SOCKET ConnectSocket; struct sockaddr_in clientService = {}; ConnectSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(ConnectSocket == INVALID_SOCKET) { return 0; } clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr(pDataArray->cGlobalIP); clientService.sin_port = htons(atoi(pDataArray->cGlobalPort)); const char *szQuery = "\xff\xff\xff\xff" "\x02" "getstatus."; while(1) { sendto(ConnectSocket, szQuery, strlen(szQuery), 0, (SOCKADDR *)&clientService, sizeof(clientService)); //blablabla :D } return 1; }
-
Habe jetzt mehr oder weniger herausgefunden das sich alle 7 Threads um die selbe(letzte) IP kümmern... schon sehr komisch.. ich übergebe dem jeweiligen Thread doch einmalige Daten.
-
Dann zeig mal den gesamten Code in "while(!fServer.eof())".
-
In der Text Datei liegt die IP und der Port in diesem Format: "IP:PORT" vor, jeweils pro Zeile.
Hier ist der Ausschnitt zum splitten(eher noch provisorisch klappt aber ohne Probleme):while(!fServer.eof()) { //String teilen fServer.getline(cServer, sizeof(cServer)); string szServer = cServer; int nColon = szServer.find(":"); size_t nIP; size_t nPort; char cIP[50]; char cPort[20]; nIP = szServer.copy(cIP, nColon, 0); cIP[nIP] = '\0'; nPort = szServer.copy(cPort, szServer.length(), nColon + 1); cPort[nPort] = '\0'; //Thread erstellen int i = 0; pDataArray[i] = (PMYDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA)); pDataArray[i]->cGlobalIP = cIP; pDataArray[i]->cGlobalPort = cPort; hThreadArray[i] = CreateThread(NULL, 0, Server, pDataArray[i], 0, &dwThreadIdArray[i]); i++; }
-
Die Variablen cIP/cPort leben bis zum Ende des Blocks, beim nächsten while-Durchlauf sind sie nicht existent. Du greifst danach aber per Zeiger drauf zu. Nur Glück, dass das "gut" geht...
-
Mh, das verwirrt mich etwas^^
Hab mich an dem Beispiel aus der MSDN gehalten in dem der Abschnitt mit den Zeigern(pDataArray[i]->cGlobalIP = cIP;) so kommentiert wird: "// Generate unique data for each thread to work with.".
Wie kann ich jedem einzelnen Thread denn sonnst einmalige Daten übergeben?...
Komm echt nich weiter...
-
Du musst doch nur dafür sorgen, dass deine Strings so lange leben, wie du sie benutzt.
Hab mal aufgeräumt. Minimal ftw
// Ungetestet/Unkompiliert und ohne Überprüfungen :D // u.A. #include <process.h> #include <string> struct MyData { std::string ip; std::string port; }; unsigned int __stdcall ServerThread(void* param) { MyData* myData = (MyData*)param; // Daten gültig delete myData; return 0; } int main(int argc, char** argv) { WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); std::ifstream file(argv[1]); std::string row; while(std::getline(file, row)) { unsigned int pos = row.find(":"); MyData* myData = new MyData; myData->ip = row.substr(0, pos); myData->port = row.substr(pos + 1); _beginthreadex(0, 0, ServerThread, myData, 0, 0); // CreateThread() hat ein leak } file.close(); std::cin.get(); // Whatever }
-
Danke funktioniert perfekt!
Werd mich wohl doch besser noch mit Threads aus einander setzen müssen.