Sockets identifizierung
-
Moin,
ich hab ein Problem (sonst wär auch nicht hier :-)).
Ich würde gern ein Programm schreiben, das als Server arbeiten soll und mit 10 Clients gleichzeitig Verbunden sein soll, dazu habe ich eine Klasse von CAsyncSocket abgeleitet und und sie angepasst.In meiner Dialogfeldklasse, habe ich dann folgende Variablen deklariert:
CNetz m_sConnectSocket[10]; //CNetz ist der Name Klasse die von
CNetz m_sListenSocket[10]; //CAsyncSocket Abgeleitet wurdeDas ganze Funktioniert auch ganz gut die Variablen werden initialisiert und warten auf eine Verbindung, jedoch wenn die Verbindung zustande kommt, kommt auch das Problem. Der Server kann die Verbindung nicht annehmen, da ich nicht weiss welche dieser zehn Variablen eine Verbindung hergestellt hat, da ja jede Variable die gleiche Funktion der Dialogfeldklasse aufruft. Die Nachfolgende Funktion wird ausgeführt, wenn eine Verbindung zustande kommt.
void CNetz::OnAccept(int nErrorCode)
{
// Sind Fehler aufgetreten?
if (nErrorCode == 0)
// Nein, OnAccept-Funktion des Dialogfelds aufrufen
((CServerDlg*)m_pWnd)->OnAccept();}
//Diese Funktion wird dann in der Dialogfeldklasse ausgeführt
void CServerDlg::OnAccept()
{
m_sListenSocket[¿].Accept(m_sConnectSocket[¿]);
}Wie bekomme ich nun die Nummer (¿) der Variable raus, die die Funktion ausgelöst hat. Wenn ich einfach alle annehme, gibs natürlich Probleme, da nur ein Client sich Verbinden kann, jeder weitere lässt das Programm abstürzen.
Wenns weiterhilft ich habe den Quellcode aus "C++ in 21 Tagen" fast identisch übernommen, bis auf eben das Anlegen von 10 statt einer Variable.
Ich hoffe ihr könnt mir weiterhelfen, da ich nirgendwo sonst etwas dazu gefunden habe, wo es um mehr als eine Verbindung gleichzeitig geht.
Danke im Vorraus
-
Ich glaube eher, Du hast nicht verstanden, was Du da programmiert hast ...
Apropos gibts hier Code-Tags. Diese sind dazu da, den Code besser sichtbar zu machen. Also bitte benutzen !!!
void CNetz::OnAccept(int nErrorCode) { // Sind Fehler aufgetreten? if (nErrorCode == 0) // Nein, OnAccept-Funktion des Dialogfelds aufrufen ((CServerDlg*)m_pWnd)->OnAccept(); } //Diese Funktion wird dann in der Dialogfeldklasse ausgeführt void CServerDlg::OnAccept() { m_sListenSocket[¿].Accept(m_sConnectSocket[¿]); }
ist zu ändern in:
void CNetz::OnAccept(int nErrorCode) { // Sind Fehler aufgetreten? if (nErrorCode == 0) // Nein, OnAccept-Funktion des Dialogfelds aufrufen for( int id=0; id<10; id++) if( &m_sConnectSocket[id] == this) { ((CServerDlg*)m_pWnd)->OnAccept( id); break; } } void CServerDlg::OnAccept( int id) { m_sListenSocket[id].Accept(m_sConnectSocket[id]); }
[ Dieser Beitrag wurde am 24.02.2003 um 12:10 Uhr von RenéG editiert. ]
-
So eigentlich garnicht außer du willst jeden Client an einem andern Port connecten.
Den Listensocket benötigst du nur einmal da es auch nur eine Port gibt auf den du listen musst.
Sollte ein Connect reinkommen erstellt du mit new eine neue Instanz des Socketspeicherklasse welche als verketete Liste erstellt werden muss.
Nicht vergessen diese mit delete wieder zu löschen.
In dieser Klasse speicherst du dann den Socket.
Weiters in dieser Klasse kannst du auch die Clientip, etc. speichern.
Sollten jetzt alle Clients connectet sein und einer Sendet etwas so empfängt die AsyncKlasse und sendet an seine Übergeordnete Klasse das Daten anstehen.
Hier bekommst du auch eine Socket geliefert.
Nun läufst du die Liste durch und vergleichst den gelieferten Socket mit dem in der liste und somit hast du eine Zeiger auf die Daten des Clienten.
Wenn nur MAX 10 Clienten connecten dürfen musst du eine int definieren welche die Anzahl der verbindungen speichert und wenn > 10 dann kein Accept mehr durchführen.[ Dieser Beitrag wurde am 24.02.2003 um 12:19 Uhr von Unix-Tom editiert. ]
-
Danke euch.
Ih hab den Quelltext gleich mal wie von RenéG gezeigt geändert und es funktioniert, nur für alle die grade was ähnliches programmieren sollte noch gesagt sein, dassif( &m_sConnectSocket[id] == this)
noch weiter in:
if( &((CServerDlg*)m_pWnd)->m_sConnectSocket[id] == this)
geändert werden muss, da m_sConnectSocket nicht gefunden werden kann, da es in der Basisklasse definiert ist.
-
Zu früh gefreudt, die Schleife
if( &((CServerDlg*)m_pWnd)->m_sConnectSocket[id] == this)
ist nie erfüllt, ich hab das problem jetzt anders gelöst, doch wie veröffentlich ich hier besser nicht, da sonst einige Leute noch einen Herzinfaktbekommen. Aber ich kann versichern, das ich nicht für jeden Socket/Port eine eigene Klasse erstellt habe.