Multi-Clienet-Messenger-Server
-
hi alle zusammen,
ich bin zur zeit im rahmen eines softwareprojektes dabei mit visual c++ einen multi-client-messenger zu programmieren (ähnlich icq, nur weniger komplex)erstmal eine funktionierende ein-client-server-anwendung zu schreiben hat zwar etwas gedauert, aber ich habs hinbekommen. nun haperts bei dem "multi-client-part"
dazu hab ich auch n entsprechendes tutorial für C gefunden (http://www.c-worker.ch/tuts/select.php), aber leider ist die umsetzung ins objektorientierte vc++ nich ganz so einfach, wie ich gehofft habe.
vlt findet sich ja jemand, der mir dabei weiter helfen kann. (in der sufu hab ich nix gefunden... evtl hab ich aber auch nur nach den falschen schlagwörtern gesucht...)also komme ich mal zu meinem ersten problem:
ich habe eine klasse "server" geschrieben
server.h#pragma once namespace Softwareprojekt_12082010 { using namespace System; using namespace System::Net; using namespace System::Net::Sockets; public ref class server { public: server(void); ~server(void); Socket^ tcpListener; Socket^ client; int^ port; int^ connected; int^ n_received; array<Socket^>^ clients; // liste von max 10 client-sockets fd_set* fdSet; // Set von genutzten client-sockets array<Byte>^ s_msg; // zwei arrays zur nachichten-übertragung array<Byte>^ r_msg; // void lauschen(); // diverse funktionen zum verbindungsaufbau und co void empfangen(); // void senden(); // void trennen(); // void set_erstellen(); // }; //---------------------------------------------------------------- }
und hier tauchen mir n paar fehler auf, wo ich mir einfach nur denke "HÄÄ??" und keine ahnung habe, wie ich sie bewältigen soll...
z.B.
No.1 in Zeile 19
"error C2440: '=' : cannot convert from 'SOCKET' to 'System::Net::Sockets::Socket ^'"No.2 in Zeile 43
"error C2446: '==' : no conversion from 'System::Net::Sockets::Socket ^' to 'SOCKET'"No.3 in Zeile 43
"error C2040: '==' : 'SOCKET' differs in levels of indirection from 'System::Net::Sockets::Socket ^'"No.4 in Zeile 43
"error C2440: '=' : cannot convert from 'System::Net::Sockets::Socket ^' to 'SOCKET'"No.5 in Zeile 47
"error C2446: '!=' : no conversion from 'SOCKET' to 'System::Net::Sockets::Socket ^'" (vermutlich weil zeile 19 schon nich funktioniert hat...)No.6 in Zeile 47
"error C2040: '!=' : 'System::Net::Sockets::Socket ^' differs in levels of indirection from 'SOCKET'"No.7 in Zeile 49
"error C2446: '==' : no conversion from 'System::Net::Sockets::Socket ^' to 'SOCKET'"No.8 in Zeile 49
"error C2040: '==' : 'SOCKET' differs in levels of indirection from 'System::Net::Sockets::Socket ^'"No.9 in Zeile 49
"error C2440: '=' : cannot convert from 'System::Net::Sockets::Socket ^' to 'SOCKET'"server.cpp
#include "StdAfx.h" #include "WinSock2.h" #include "windows.h" #include "server.h" #define MAX_CLIENTS 10 namespace Softwareprojekt_12082010 { server::server(void) : connected(0), n_received(0) { s_msg = gcnew array<Byte>(1024); r_msg = gcnew array<Byte>(1024); clients = gcnew array<Socket^>(MAX_CLIENTS); for ( int i = 0; i < MAX_CLIENTS; i++ ) { clients[i] = INVALID_SOCKET; // der versuch, die socket-liste, bzw alle enthaltenen sockets auf invalid zu setzen } } server::~server(void) { } void server::lauschen() { connected = 1; tcpListener = gcnew Socket( AddressFamily::InterNetwork, SocketType::Stream, ProtocolType::Tcp ); IPEndPoint^ ipep = gcnew IPEndPoint( IPAddress::Any, (int)port ); tcpListener->Bind( ipep ); tcpListener->Listen( (int)SocketOptionName::MaxConnections ); return; } void server::set_erstellen() { FD_ZERO( fdeSet ); // Set leereln FD_SET( tecpListenerw, fdSet ); // Socket, welcher Verbindung annimmt zu Set hinzufügen for ( int i = 0; i < MAX_CLIENTS; i++ ) // alle gültigen Client-Sockets zu Set hinzufügen (keine INVALID_SOCKETs) { if ( clients[i] != INVALID_SOCKET ) { FD_SET( clients[i], fdSet ); } } } void server::empfangen() { /*...*/ } void server::senden() { */...*/ } void server::trennen() { /*...*/ } //--------------------------------------------- }
ich vermute mal, dass da möglicherweise n teil an ner falschen zeiger-zuweisung liegt... ich seh da iwie selber nich mehr ganz durch :o(
ich hoffe, ihr könnt mir weiterhelfen
danke schon mal!PS: ich arbeite mit Visual C++ 2008 Express Edition
PPS: der code ist natürlich bei weitem noch nicht vollständig, ich bin grade dabei ihn auf mulit-client umzuschreiben. die funktionen lauschen, empfangen, senden und trennen funktionieren im "ein-client-betrieb" problemlos
-
Du bringst da einiges durcheinander...
Da du ja mit C++/CLI (also dem .NET-Framework) arbeitest, kannst du auch direkt dessen Klassen sowie Eigenschaften benutzen (ohne auf die direkten SOCKET-Funktionen zuzugreifen).
Nur wenn du komplett auf .NET verzichten willst (und dein Projekt dann von C++/CLI auf reines C++ umstellst) benötigst du direkten Zugriff (wie im Tutorial beschrieben).
P.S. Wie kommt es eigentlich, daß jeder Anfänger mit dem "MS Visual C++" zuerst ein C++/CLI - Projekt startet?
-
P.S. Wie kommt es eigentlich, daß jeder Anfänger mit dem "MS Visual C++" zuerst ein C++/CLI - Projekt startet?
ka ^^ eiglich *sollte* ich ja kein anfänger mehr sein... aber is schon ne weile her, dass ma das im studium hatten und naja, damals war ich auch nich grad die hellste leuchte.
zu deiner antwort... hilft mir leider grad nich viel weiter :o(
-
Aber du mußt doch wissen, ob du jetzt bei .NET bleiben willst oder nicht?
Wenn ersteres, dann schmeiß' den ganzen SOCKET-Kram raus und ersetzt ihn entsprechend durch die vom .NET vorgegebenen Klassen bzw. Methoden/Eigenschaften.Um den Socket auf "invalid" zu setzen, reicht ja einfach:
clients[i] = nullptr;
P.S. desweiteren kann ich dir für C++/CLI und GUI nur den entsprechenden Beitrag aus dem SubForum empfehlen: http://www.c-plusplus.net/forum/viewtopic-var-t-is-263084.html d.h. steig dafür dann auf C# um...
-
also ich möchte schon bei .NET bleiben, schließlich is ja der rest der progs auch mit .NET geschrieben (außerdem... ich *darf* nich auf C# umsteigen, da ne vorgabe is das projekt objektorientiert mit vc++ zu schreiben)
aber was meinst du mit "schmeiß' den ganzen SOCKET-Kram raus"?
ich nehm ma an, dass nur der kram ausm tut wieder weg muss, oder?kannst du mir da bitte verklickern, wie ich das prog da am besten mit .NET multiclient-fähig bekomme?
denn, wie in dem tut beschriebem, hab ich halt das problem, dass der server, während er auf ne antwort vom 1. client wartet, der sich angemeldet hat nix anderes machen kann, d.h. auch keine neuen clients anmelden usw...
und wenn es sich vermeiden lässt, würd ich auch gerne drauf verzichten für jeden Client einen eigenen Prozess oder Thread zu starten, weil die muss man ja auch alle wieder vernünftig beendet bekommen, was, wie ich mir sagen lassen hab, ne große fehlerquelle sein kann. von daher klang die methode mit select() nich schlecht... aber wie stell ich das nun mit .NET an?
-
Für select() gibt es bereits eine Kapselung im .NET Framework: Socket.Poll
Performanter sind aber die asynchronen Methoden: Socket.BeginReceive, Socket.BeginSend
-
Für select() gibt es bereits eine Kapselung im .NET Framework: Socket.Poll
danke, danke, danke!!!
das hat mir extrem weitergeholfen!
jetzt funzt es so, wie ich wollte, der rest is nur noch feinschliff