Döende sockets, kaboom
Håller på att göra klient/server-program med .net sockets. Har fått allting att fungera förutom att när tex klienten dör, utan att stänga socketen, dör server också :(. Och jag får upp en otäck JIT-ruta ("which debugger do you want to use") när servern dör :(
Så vad jag vill ha är ett sätt att märka när klienten dör och då ta bort socketen från servern.
Svara
Sv: Döende sockets, kaboom
Lyssnar inte bara servern på en port? Då borde den inte då om klienten dör då de inte ens är ihopkopplade.
Mvh Johan
Svara
Sv:Döende sockets, kaboom
Eh? :P
Servern har en loop som kör:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | while ( true ) { Client newClient = new Client( /*listener.AcceptSocket()*/ ); newClient.Connected += new Client.ConnectedDelegate(newClient_Connected); newClient.Disconnected += new Client.DisconnectedDelegate(newClient_Disconnected); newClient.DataReceived += new Client.DataReceivedDelegate(newClient_DataReceived); newClient.Connect(listener.AcceptSocket()); lock (clients) { clients.Add(newClient.Id, newClient); } /* * Dim params() As Object = {"New connection"} Me.Invoke(New StatusInvoker(AddressOf Me.UpdateStatus), params) */ } |
listener.AccepSocket() låser tråden
När den får en ny socketansl körs följande:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public void Connect(Socket client) { this .client = client; connected = true ; try { client.BeginReceive(readBuffer, 0, readBuffer.Length, SocketFlags.None, new AsyncCallback(ReadAsyncMethod), null ); } catch { connected = false ; } } |
och när data kommer in körs den här funktionen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | private void ReadAsyncMethod(IAsyncResult ar) { int byteCount; //try { byteCount = client.EndReceive(ar); Debug.WriteLine( "ByteCount: " +byteCount.ToString()); if (byteCount < 1) { connected = false ; return ; } BuildReadString(readBuffer, 0, byteCount); SocketError ERROR = new SocketError(); if (connected && client.Connected) client.BeginReceive(readBuffer, 0, readBuffer.Length, SocketFlags.None, out ERROR, new AsyncCallback(ReadAsync), null ); Debug.WriteLine(ERROR.ToString()); } //catch /*(Exception e)*/ { //DISCONNECTED // connected = false; } } |
och efter att funktionen har anropat sig själv med beginreceive tar servern emot mer data, men om socketen istället dör, så dör servern (vilket i sin tur leder till att resten av klienterna dör :S)
Det intressanta är att det funkar när jag låser tråden:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | private void ReadAsyncMethod( /*IAsyncResult ar*/ ) { int byteCount; //try { //byteCount = client.EndReceive(ar); /*Debug.WriteLine("ByteCount: "+byteCount.ToString()); if (byteCount < 1) { connected = false; return; } BuildReadString(readBuffer, 0, byteCount);*/ SocketError ERROR = new SocketError(); if (connected && client.Connected) client.Receive(readBuffer); //client.BeginReceive(readBuffer, 0, readBuffer.Length, SocketFlags.None, //out ERROR, new AsyncCallback(ReadAsync), null); Debug.WriteLine(ERROR.ToString()); Debug.WriteLine( "" ); ReadAsyncMethod(); } //catch /*(Exception e)*/ { //DISCONNECTED // connected = false; } } |
Får en socketexception, men programmet kan fortsätta med try..catch nu
Edit.
När jag kör synkat kan jag anv SocketError och slipper try catch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | private void readLoop() { while (readMethod()) { } } private bool readMethod() { int byteCount = new int (); SocketError error = new SocketError(); if (connected && client.Connected) { byteCount = client.Receive(readBuffer, 0, readBuffer.Length, SocketFlags.None, out error); Debug.WriteLine(error.ToString()); if (error != SocketError.Success) { Console.WriteLine( this .id + ": " + error.ToString()); connected = false ; return false ; } return BuildReadString(readBuffer, 0, byteCount); } return false ; } |
Svara