TcpCleint: stream->Read() wirft eine Exception
-
Hallo,
ich will zwei selbstgeschriebene Programme über Socket mit einander kommunizieren zu lassen. Ich verwende VS9 SP1 und .NET Framework 3.5.
Den Code für die Kommunikation habe ich zwar fast zu 100% von MSDN übernommen, jedoch wirft mir stream->Read(...) folgende Exception:
Von der Übertragungsverbindung können keine Daten gelesen werde: Eine vorhandene Verbindung wurde vom Remotehost geschlossen.Codesnippet vom Server:
using namespace System; using namespace System::IO; using namespace System::Net; using namespace System::Net::Sockets; using namespace System::Text; using namespace System::Threading; // usw //... void SocketThread() { Int32 port = 30030; IPAddress^ localAddr = IPAddress::Parse( "127.0.0.1" ); TcpListener^ server = gcnew TcpListener( IPAddress::Parse( "127.0.0.1" ),port ); server->Start(); array<Byte>^bytes = gcnew array<Byte>(256); String^ data = nullptr; while ( true ) { TcpClient^ client = server->AcceptTcpClient(); data = nullptr; NetworkStream^ stream = client->GetStream(); Int32 i; while ( i = stream->Read( bytes, 0, bytes->Length ) ) // HIER passiert die o.g. Exception nach dem der verbundene Client (unterer Codesnippet) die verbindung beendet { data = Text::Encoding::ASCII->GetString( bytes, 0, i ); array<Byte>^msg = Text::Encoding::ASCII->GetBytes("habs empfangen"); stream->Write( msg, 0, msg->Length ); } client->Close(); } }
Codesnippet vom Client:
using namespace System; using namespace System::IO; using namespace System::Net; using namespace System::Net::Sockets; using namespace System::Text; using namespace System::Threading; // usw //... void SocketThrad() { Int32 port = 30030; TcpClient^ client = gcnew TcpClient( "127.0.0.1",port ); array<Byte>^data = gcnew array<Byte>(256); data = Text::Encoding::ASCII->GetBytes( "blabla" ); NetworkStream^ stream = client->GetStream(); stream->Write( data, 0, data->Length ); data = gcnew array<Byte>(256); String^ responseData = String::Empty; Int32 bytes = stream->Read( data, 0, data->Length ); responseData = Text::Encoding::ASCII->GetString( data, 0, bytes ); // hier wird noch ein paar mal hin und her gesendet client->Close(); // und nach Ausführen dieser Zeile bekomme ich die o.g. Exception }
Ich hoffe ihr könnt mir helfen.
Vielen Dank im Voraus!
Gruß Eugen
-
Moin,
Du hast doch schon selber die Lösung
... nach dem ausführen der Zeile
client->Close()
kommt Die Exception
Von der Übertragungsverbindung können keine Daten gelesen werde: Eine vorhandene Verbindung wurde vom Remotehost geschlossen
ja klar ... Du schließt ja auch die Verbindung ... die Exception muss kommen
Du musst dem Server klar machen das Du die Verbindung beenden willst ... dazu kannst Du die Exception nehmen um ihm das hart zu sagen -> try-catch-Konstrukt ... oder Du bastelst Dir ein Protokoll für die Kommunikation zwischen Server und Client
hand, mogel
-
Ich dachte eigentlich dass stream->Read() beim Versuch nach dem Close() zu lesen einfach eine 0 zurückgibt und der Server springt aus der Schleife raus. So ähnlich war dies nämlich beim klassischen WinSock mit recv(...) von dem ich eigentlich eben weggegangen bin
Gibts nichts anderes ohne Exceptions und eigene Protokolle?
-
Ich dachte eigentlich dass stream->Read() beim Versuch nach dem Close() zu lesen einfach eine 0 zurückgibt und der Server springt aus der Schleife raus. So ähnlich war dies nämlich beim klassischen WinSock mit recv(...) von dem ich eigentlich eben weggegangen bin
Nun, offensichtlich ist das nicht so.
Gibts nichts anderes ohne Exceptions und eigene Protokolle?
Exceptions sind ein wichtiger Bestandteil von .NET und den Sprachen C# und auch C++/CLI. Deshalb ist es auch nicht verwunderlich, dass das Error Reporting über Exceptions geschieht.
Es ist also ganz einfach: Programmiere mit C++/CLI und dem .NET Framework so wie es vorgesehen ist. Und da gehören Exceptions dazu.
Simon
-
Wenn der Remotehost die Verbindung schließt und alle verfügbaren Daten empfangen wurden, wird die Read-Methode sofort abgeschlossen, und diese gibt 0 (null) Bytes zurück.
-
probier mal stream->Close() statt client->Close()
-
Lag tatsächlich am Fehlen von stream->Close() auf der Seite vom Client
Schande für MS, dass der Befehl im msdn Codebeispiel nicht dabeistand. Wenn man da erst einsteigt übersieht man sowas sehr schnell.
Vilen Dank an alle Poster