Threading
-
Hallo,
ich befasse mich erst seit kurzem mit Winsock-Funktionen (und C/C++ allgemein) und habe glücklicherweise auch schon viel Erfolg gehabt!
Da gewisse Funktionen "blockling calls" sind möchte ich das mit einem Thread lösen.
Im Detail schreibe ich ein Sampel, welches Daten senden und empfangen können soll.
Nun möchte ich einen Thread erzeugen damit ich paralell zum senden auch Daten empfangen kann, d.h. das Empfangen der Daten soll in einem Thread durchgeführt werden.
Mir sind bereits auch Funktionen wie CreateThread(....) bekannt, allerdings habe ich beim implementieren Probleme bzw. bekomme gar nichts auf die Reihe
Ich wäre dankbar für ein paar Zeilen Code, die einen Thread erzeugen, sodass ich dies an einem lauffähigen Programm nachollziehen kann.Mir ist bekannt das es auch andere Lösungsalternativen gibt, aber ich möchte das unbedingt so realisieren.
P.S.: Habe auch schon das Forum durchstöbert, allerdings hat mir das nicht geholfen, bitte auch keine MSDN Links, danke.
Vielmals danke für die Hilfe!!
-
http://www.c-worker.ch/, ich glaub dort wirst du fündig.
-
bau ein kleines programm wo du versuchst threads zu verwenden, dann poste es hier und wir können mal drüberschauen.
-
Hi, hier ist ein Ausschnitt aus meinem Code, in welchem ich versuche einen Thread zu verwenden.
Nach 'accept' soll ein weiterer Thread geöffnet werden, der für den Empfang der Daten zuständig ist..... acceptSocket = accept(mysocket, NULL,NULL); // sobald eine Verbindung über angenommen wurde soll nun der Thread gestartet // werden. HANDLE hNewRecvThread; hNewRecvThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)RecvThread, NULL, NULL, NULL);Der Thread sollte nun erstellt sein und im Hintergrund laufen oder?
Die Funktion RecvThread beinhaltet folgenden Code:
void RecvThread() { int rc; /* Variable fuer Rueckgabewerte */ char incoming[256]; int rc; rc = recv(mysocket, incoming, strlen(incoming),0); //cout << incoming << endl;Nun aber: Wie übergebe ich den Socket mysocket der Funktion Recvthread() so das dieser ihr bekannt ist?
Geht das überhaupt so wie ich das mache?Bitte um Hilfe und bedanke mich gleich mal dafür

Gruß
-
CreateThread - 4. Parameter
-
Und die Threadproc muss die folgende Signatur haben:
DWORD WINAPI ThreadProc(LPVOID lpParameter);Dann brauchst du den Cast auch nicht mehr
-
Ok du meinst also der 4te Parameter der CreateThread()-Funktion soll den Namen ThreadProc() haben.
Das sieht dann so aus:
hNewRecvThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, NULL, NULL);ThreadProc() sieht nun so aus:
DWORD WINAPI ThreadProc( LPVOID lpParam ) { char recBuf[256]; recv(mysocket, recBuf, sizeof(recBuf), NULL); cout << recBuf << endl; return 0; }Da die Funktion außerhalb von main()
deklariert wurde ist ihr natürlich der Parameter "mysocket" nicht bekannt.
Dieser wird aber unbedingt benötigt, um die Daten zu senden.(???)
Mache ich hier einen Denkfehler und kann mir jemand sagen, was ich falsch mache?
-
Für WinAPI bist du noch nicht reif genug wenn man deinen Beitrag so liest.
-
Das kann schon gut sein, das er dafür nicht "reif" genug ist, aber wie soll den etwas wachsen wenn du ihm so eine schlechte antwort gibst? wahrscheinlich hast du keine ahnung.
-
Hallo man sollte _beginthreadex benutzen und nicht CreateThread.
-
du hast zwei moeglichkeiten:
A: mysocket machst du zu einer globalen variableB: Die Funktion die parallel ausgefuehrt werden soll ( in deinem Fall: ThreadProc ) kann genau einen parameter haben und dieser ist ein int oder ein pointer also 4 byte lang. SOCKET ist auch 4 byte lang also kannst du direkt deinen mysocket uebergeben oder aber du nutzt diese 4 byte als pointer und laesst ihn auf deinen mysock zeigen. Musst halt dann dafuer sorgen das mysocket gueltig ist wenn recv() drauf zu greifen will
-
Vielen Dank!
Deine Hilfe hat mir sehr geholfen!
-
Ich habe ein ähnliches Problem.
Ich starte den Thread ebenso wie anfänger
mit CreateThread und rufe eine Funktion, welche für den Empfang der Daten zuständig ist.Hat sich mein Client mit dem Server verbunden was auch geht, haben beide die Möglichkeit Daten zu senden bzw. Text.
Der Thread müsste doch immer die Daten ausgeben die empfangen wurden oder? So habe ich das implementiert. Ich meine er läuft doch im Hintergrund?
Ich hoffe das ist nicht allzu ungenau. Gebe euch natürlich gerne alle Infos die ihr benötigt.Vielen Dank!
-
Hier ist der Server:
#include <stdio.h> #include <winsock2.h> #include <iostream> using namespace std; #pragma comment( lib, "ws2_32.lib" ) using namespace std; //#include <process.h> nur für benginthread(ex) benötigt SOCKET acceptSocket; DWORD WINAPI ThreadProc() { for(;;) { char recBuf[256]; int receive; receive = recv(acceptSocket, recBuf, sizeof(recBuf), NULL); cout << "" << endl; return 0; } //for } int StartWinsock() { ; WSAData wsaData; WORD wVersion = MAKEWORD(2,0); return WSAStartup(wVersion, &wsaData); } int main() { int retStartup; retStartup = StartWinsock(); if(retStartup!=0) { cout << "Error WSAStartup: " << WSAGetLastError() << endl; } SOCKET mysocket; //Basic //Verbindungsannahme, wartet nur auf Verbindungen mehr nicht mysocket = socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addr; char ServerAdress[] = "127.0.0.1"; memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; // Adress Familie addr.sin_port = htons(12345); // Socket an Port 12345 binden addr.sin_addr.s_addr = inet_addr(ServerAdress); bind(mysocket, (SOCKADDR*)&addr, sizeof(addr)); listen(mysocket, SOMAXCONN); int addrlen = sizeof addr; cout << "Mein simpler Chat, Version 1.0" << endl; cout << "*** Matthias Heil 2005 ***" << endl; cout << "Waitung for incoming connection... " << endl; acceptSocket = accept(mysocket, NULL,NULL); if(acceptSocket != SOCKET_ERROR) { cout << "Client connected" << endl; } CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, 0, NULL); for(;;) { char message[256]; cout << "Enter Message to send:"; cin.getline(message, 256); sendto( acceptSocket, message, sizeof(message)+1, 0, NULL, NULL); } //for return(0); }
-
Hier ist der Client:
#include <iostream> #include <stdio.h> #include <winsock2.h> using namespace std; #define SERVER_PORT 12345 SOCKET sock; //Global!!! DWORD WINAPI ThreadProc() { for(;;) { char incoming[256]; recv(sock, incoming, sizeof(incoming),NULL); cout << "" << endl; cout << "Incoming: " << incoming << endl; return 0; } //for } long go() // Socket-Service starten (unter Windows erforderlich). { long rc; WSADATA wsaData; // WSADATA-Objekt erstellen. WORD wVersionRequested; wVersionRequested = MAKEWORD(2,1); // zu Verwendene Version: 2.1. // mit MAKEWORD-Makro WORD-Wert erstellen rc = WSAStartup(wVersionRequested, &wsaData); // WSAStartup aufrufen return rc; /* siehe: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsastartup_2.asp */ } void main() { SOCKADDR_IN addr; //long rc; char hostAdress[] = "127.0.0.1"; //WSAStartup aufrufen go(); //Socket anlegen sock=socket(AF_INET,SOCK_STREAM,NULL); // Informationen fuer Verbindung addr.sin_family = AF_INET; addr.sin_port = htons(SERVER_PORT); addr.sin_addr.s_addr = inet_addr(hostAdress); //Socket mit Server verbinden, endlos immer wieder probieren while(connect(sock, (SOCKADDR*)&addr, sizeof(SOCKADDR)) == SOCKET_ERROR) { printf("."); // Lebenszeichen ausgeben Sleep( 500 ); // 500ms warten } // Wenn Server gefunden... printf("Verbunden"); cout << "" << endl; CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadProc, NULL, NULL, NULL); for(;;) { char message[256]; cout << "Enter Text to send: "; cin.getline(message, 255); //sprintf(message, "Hi I am the client!!!"); sendto( sock, message, sizeof(message)+1, 0, NULL, NULL); } }
-
Wenn dein Programm die C-Runtime verwendet solltest du CreateThread() durch _beginthreadex() ersetzen sonst könnte es zu Problemen kommen.
-
Mach erstmal den (LPTHREAD_START_ROUTINE)-Cast weg. Ist unnötig wenn die Threadfunktion die richtige Signatur hat.

Ok, hilft aber alles nix beim deinem Problem.
-
Chew-Z schrieb:
Wenn dein Programm die C-Runtime verwendet solltest du CreateThread() durch _beginthreadex() ersetzen sonst könnte es zu Problemen kommen.
Ja dazu is dann <process.h> erforderlich. Denkst du echt das es daran liegt?
Ist die sonst nichts aufegefallen?