Threads Sockets Server und Client????
-
Hallo,
Folgendes Problem:
Ich bin dabei, ein Progamm zu schreiben, welches gleichzeitig als Server und Client laufen soll. Also der Severthread soll ständig Verbindungen akzeptieren, und der ClientThread soll ständig versuchen sich mit dem Server zu verbinden.Das ist der Serverthread:
int CServerThread::Run() { CString daten; int iRcvd; int status = 0; CAsyncSocket sockSrvr; CAsyncSocket sockRecv; int TCP_PORT=4000; running=TRUE; int ret = 0; while(running==TRUE) { AfxSocketInit(NULL); sockSrvr.Create(TCP_PORT,SOCK_STREAM,NULL); sockSrvr.Listen(); ret = sockSrvr.Accept(sockRecv); while(ret==0) { sockSrvr.Close(); // MessageBox(NULL,"Fehler beim Accept","Thread",MB_OK); ret = sockSrvr.Accept(sockRecv); Sleep(10); } sockSrvr.Close(); char *pBuf = new char[100]; iRcvd = sockRecv.Receive(pBuf, 100); pBuf[iRcvd] = NULL; daten = pBuf; delete []pBuf; sockRecv.Close(); MessageBox(NULL,daten,"Thread",MB_OK); Sleep(1); } return 0; }
Und das der ClientThread:
int CClientThread::Run() { running=TRUE; int TCP_PORT=4000; CAsyncSocket sockSrvr; int ret = 0; int iRcvd; CString daten="Hallo"; while(running==TRUE) { AfxSocketInit(NULL); ret = sockSrvr.Connect("192.168.1.30",TCP_PORT); while(ret == 1) { // MessageBox(NULL,"Kann keine Verbindung herstellen","Thread",MB_OK); sockSrvr.Close(); ret = sockSrvr.Connect("192.168.1.30",TCP_PORT); } char *pBuf = new char[100]; pBuf="Hallo"; iRcvd = sockSrvr.Send(pBuf, 100); pBuf[iRcvd] = NULL; delete []pBuf; sockSrvr.Close(); } Sleep(1); return 0; }
Ich starte die Threads per Button. Ich bekomme aber immer nen Fehler, also "ret=0" Nie kommt ne Verbindung zustande....
Vielleicht kann mir ja jemand sagen, was ich falsch mache.MfG Lunix
-
Sind ja auch asynchrone Sockets.
Dafür gibts die virtuelle Methoden:
OnAccept
OnClose
OnConnect
OnReceive
OnSend
OnOutOfBandDataEinfach überschreiben.
Für den Server dann z.B.
CMyDlg::InInitDialog() { //... m_myserver.Create(); m_myserver.Listen(); }
-
Also wenn ich die Funktionen übschreiben will, muss ich ja von CAyncSockets erben? Aber Threads laufen ja jeweils in einer eigenen Klasse von CWinThread abgeleitet. Wie soll ich das jetzt anstellen? Oder verstehe ich da irgendwas falsch?
Normalerweise würde ich ja dann in der OnAccept dann ausführen myListenSocket.Accept(neuerSocket) und in OnReceive dann neuerSocket.Receive(...). Aber an welcher Stelle führe ich dann die Überschreibungen durch??
-
Du überschreibst alle benötigten On* Methoden. Threads brauchst du dann nicht unbedingt. Es gibt aber auch noch CSocket - die sind dann nicht mehr asynchron.
Wenn dann dein Server "läuft" und jemand eine Verbindung mit deinem Rechner herstellen möchte dann wird OnAccept aufgerufen. Dort drinnen kannst du dann Accept aufrufen.
-
Das Problem dabei ist aber, das die beiden Thread ständig laufen sollen. Der Server soll ständig neue Clients annehmen und die Adressen speichern. Und die Clients sollen ständig senden, das sie vorhanden sind. Meiner Meinung nach lässt sich das nur mit Threads realisieren?
MfG Lunix
-
Also um das "Warten auf Clients" brauchst du dich nicht kümmern - das macht CAsyncSocket für dich schon. (Accept musst nat. noch aufrufen)
Wieso sollen die Clients ständig senden das sie da sind? Wenn ein Client die Verbindung schließt dann wird OnClose aufgerufen.
-
Na sonst brächte ich ja für jeden Client einen anderen Port? So kann ich ständig überprüfen, ob jemand sendet. Das heisst, ich will einfach nur alle CLients sehen, die das Programm gestartet haben. Dazu sollen die Clients immer eine Meldung senden, "Hallo ich bin da". Der Server verarbeitet die Meldungen und kann die Liste aller Clients aktuallisieren. Ungefähr so wie ICQ oder sowas ähnliches.
-
Naja - ich würde die Verbindung einfach stehen lassen.
Server könnte im Prinzip so aussehen:
class Server : public CAsyncSocket { CList<Client*,Client*> clients; public: void OnAccept() { Client* client = new Client(this); Accept(*client); clients.Add(client); } };
-
Lunix:
Ich glaube das du bei den Sockets etwas falsch verstanden hast.
Wieso brauchst du immer wieder neue Ports ?
Kurze Einführung:
Client connect auf z.B. Port 1000
Server akzeptiert und handelt mit dem Client einen neuen Port aus. z.B. 34000
Nun sind beide über diesen Port verbunden.Server wartet wieder auf Port 1000 für weitere Clients.
CSocket Socket ist in Sync.
dh.: connect, read write u.s.w. sind blockierte F0unktionen und kehren erst wieder zurück wenn die Funktion abgearbeitet ist.CAsnySocket: Wie der Name schon sagt.
connect, read, write u.s.w funktionieren nichtblockierend sondern senden an das aufrufende Programm eine Message ob angearbeitet.
OnOK
OnAccept
OnClose
OnConnect
OnReceive
OnSend
u.s.w.Um so ein Programm zu machen schau dir das Buch
VC++ 6 in 21 Tagen an. Dort wir es beschrieben.
Um mehrere Clients zu akzeptieren musst du den die Sockets in einer verketteten Liste speichern.
-
Ok, danke!
Ich werds mal so probieren. Ich kenne das Beispiel aus VC++ in 21 Tagen. Ich hatte bloss irgendwie ein Problem damit, das auf mehrere Clients zu übertragen.
Ich meld mich dann, wenn ich's geschafft habe...Bye,
Lunix