Meine Funktion wird nicht richtig abgearbeitet, find Fehler den Fehler nich??!!
-
Hallo,
ich habe mich mal daran versucht mein kleines Server/Client Programm etwas weiter auszubauen. Folgendes ich habe im Servertool eine Listbox die auftretende Events dokumentieren soll. Dazu habe ich eine Funktion geschrieben die je nach Ereignis einen String in die Listbox postet. Ich lasse diese Funktion in einen extra Thread laufen.Hier erst einmal meine Funktion:
/////////////////////////////////////////////////////////////////////////////// // # Server refresh long done; string event; char szMessageBuffer[ 512 ]; void serverWork( HWND hList, int &lIndex ) { FD_ZERO( &fdset ); FD_SET( server, &fdset ); for( int i = 0; i < MAX_CLIENTS; i++ ) { if( client[ i ] != INVALID_SOCKET ) { FD_SET( client[ i ], &fdset ); } } done = select( 0, &fdset, 0, 0, 0 ); if( FD_ISSET( server, &fdset ) ) { for( int i = 0; i < MAX_CLIENTS; i++ ) { if( client[ i ] == INVALID_SOCKET ) { client[ i ] = accept( server, 0, 0 ); InsertSysMessage( hList, lIndex, "New client is connected" ); send( client[ i ], "Welcome on board!", 17, 0 ); for( int j = 0; j < MAX_CLIENTS; j++ ) { if( j == i ) { continue; } if( client[ j ] != INVALID_SOCKET ) { send( client[ j ], "New user is connected!", 22, 0 ); } } break; } } } for( int i = 0; i < MAX_CLIENTS; i++ ) { if( client[ i ] == INVALID_SOCKET ) { continue; } if( FD_ISSET( client[ i ], &fdset ) ) { szMessageBuffer[ 0 ] = 0; done = recv( client[ i ], szMessageBuffer, sizeof( szMessageBuffer ), 0 ); if( ( done == 0 ) || ( done == SOCKET_ERROR ) ) { closesocket( client[ i ] ); client[ i ] = INVALID_SOCKET; InsertSysMessage( hList, lIndex, "Client is disconnected!" ); } else { InsertSysMessage( hList, lIndex, "Client sent a message" ); for( int j = 0; j < MAX_CLIENTS; j++ ) { if( j == i ) { continue; } send( client[ j ], szMessageBuffer, strlen( szMessageBuffer ), 0 ); szMessageBuffer[ 0 ] = 0; } } } } }Und so verwende ich sie in der Appi:
DWORD WINAPI Thread_Connection( LPVOID pParam ) { while( !fexit ) { serverWork( hListEvent, lIndex ); } SendMessage( hListEvent, LB_DELETESTRING, lIndex, 0 ); lIndex--; return (DWORD) pParam; }Mein Problem ist jetzt folgendes:
- es wird dokumentiert, wenn sich ein Client verbindet
- es wird dokumentiert, wenn ein Client disconnected
aber,- es wird nicht dokumentiert, wenn ein Client eine Nachricht schrieb
- so wird diese vom Client gesandte Nachricht auch nicht zu allen anderen Clients
geschickt
- und es wird nicht an alle anderen Clients gepostet, wenn sich ein neuer Client verbindet
hatWäre echt nett, wenn mir jemand Rat geben könnte wieso diese Dinge nicht abgearbeitet werden.
Gruß Tobi.
-
help please!
-
Hi Tübi!
- Du arbeitest offensichtlich mit MSVC; das Debugger-GUI ist das beste das ich kenne - warum debuggst Du nicht erstmal Deinen Server? Für einen Code im Enwicklungsstadium sind mir da auch erheblich zuwenige Testaussschriften drin!
- Der recv in Zeile 57 scheint ja nach Deiner Schilderung der entscheidende zu sein. Versuch's dort mal mit einem WSAGetLastError().
- Das FD_ISSET finde ich etwas seltsam; einal rufst Du's mit dem Server und einmal mit einem Deskriptor für den Client auf.
- Die Schleifensteuerung ist unkommentiert - tu was dagegen ! Für mich sieht das so aus als würde der Server nach dem ersten Client im der nächsten loop beim accept stecken bleiben. Aber ohne Kommentare werde ich da gewiss nicht tiefer einsteigen.
Grüsse
*this
-
hmm ok.... könntest du mir evtl. nen site empfehlen oder nen tutorial wo das mit dem Debuggen erklärt wird? ich hab da nämlich net so wirklich ahnung wie gemacht wir.
wäre das eine gute fehlerkontrolle?:
done = select( 0, &fdset, 0, 0, 0 ); if( ( done == 0 ) || ( done == SOCKET_ERROR ) ) { sprintf( szErrorBuffer, "%d", WSAGetLastError() ); MessageBox( 0, szErrorBuffer, "Error", MB_OK ); return; }Gruß Tobi.
-
Mir sind nicht wirklich Tutorials zu so etwas bekannt.
Am besten du machst rechts neben dem code in MSVC einen Breakpoint( einen vors recv() und einen dannach) und schaust durch was so in den Variablen steht dann wirst du merken wo der Fehler ist.MFG Pacino
-
T0bi schrieb:
hmm ok.... könntest du mir evtl. nen site empfehlen
Einfach mal ausprobieren was dann so passiert:
Mit
<F9> Toggle Breakpoint
erstmal Breaks setzen/ausschalten
zB. bei dem recv in Zeile 57.
<F5> Start Debug
<F10> Step Over
<F11> Step Into
<Shift-F5> Exit Debug
Links unten solltest Du ein Fensterli mit lokalen Variablen sehen.T0bi schrieb:
wäre das eine gute fehlerkontrolle?:
done = select( 0, &fdset, 0, 0, 0 ); if( ( done == 0 ) || ( done == SOCKET_ERROR ) ) { sprintf( szErrorBuffer, "%d", WSAGetLastError() ); MessageBox( 0, szErrorBuffer, "Error", MB_OK ); return; }Na ja; das zeigt Dir eine Zahl an, die Du dann im MSDN nachschlagen musst.
Eher so in etwa:/*global*/ std::map<int,std::string> codeMap; codeMap[WSAEINTR] = "Interrupted function call"; // 10004 codeMap[WSAACCES] = "Permission denied."; // 10013 // // .. und soweiter // int sockErr = WSAGetLastError(); std::string strMsg(""); if (::codeMap.find(sockErr) != codeMap.end()) strMsg += " => "; strMsg += codeMap[sockErr]; } std::cerr << "Winsock Error #" << sockErr << strMsg << std::endl;Und das jetzt entwder UNICODE fähig machen
#ifdef _UNICODE typedef std::wstring string; typedef std::wostream ostream; //... extern ostream& cerr; // das irgendwo mit std::cerr oder std::wcerr versosrgen //... #else // _MBCS,_SBCS typedef std::string string; //... #endifoder auf TCHAR* und <cstdio> umschreiben.
Grüsse
Gast++
P.S.: Die Arbeit rentiert sich, glaub mir!
-
eins noch... ich arbeite mit BCB6
-
T0bi schrieb:
eins noch... ich arbeite mit BCB6
Dann sind die Tastenkürzel zum Debuggen wahrscheinlich nur anders -
aber in der IDE kenn ich mich gar nicht aus.