2010-11-04 25 views
0

J'ai un serveur basé sur un socket C# qui sert les clients TCP. J'utilise la surveillance basée sur telnet pour voir si le serveur écoute. pour mettre les clients en veille, utilisez le serveur keep alive (en envoyant des données de chaîne aléatoires), et si l'attente de socket augmente, je supprime le client du dictionnaire d'un client. le probelm est: les connexions telnet à la socket ne sont pas supprimées de la liste des connexions et le nombre de clients augmente lentement mais sûrement. J'ai essayé un telnet manuellement sur le serveur via la ligne de commande et en fermant la connexion telnet - rien. Le serveur continue à envoyer le keep alive à la connexion telnet sans les execptions. ceci est mon appel relues:La connexion telnet à un socket C# ne se ferme pas

protected void ReadCallback(IAsyncResult ar) 
    { 
     String content = String.Empty; 
     // Retrieve the state object and the handler socket 
     // from the async state object. 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket handler = state.socket; 
     if (state.socket == null) 
      return; 
     if (!state.socket.Connected) 
      return; 

     int id = state.id; 
     try 
     { 
      // Read data from the client socket. 
      int bytesRead = handler.EndReceive(ar); 

      if (bytesRead > 0) 
      { 
       string newAddedStr = string.Empty; 
       newAddedStr = Encoding.UTF8.GetString(state.buffer, 0, bytesRead); 
       //cut the new message and add it 
       if (state.sb == null) 
        state.sb = new StringBuilder(); 
        state.sb.Append(newAddedStr); 
       // There might be more data, so store the data received so far. 
       //add data until end of XML 
       content = state.sb.ToString(); 
       //IF GOT FULL MESSAGE FROM SOCKET 
       if ((content.Length > 0) /*&& (content.IndexOf("\0") > -1)*/) 
       { 
        String strh = String.Format("Client # {0} data: ", id); 
        strh += content.Replace("\0", ""); 
        if (!strh.Contains("keepalive")) 
         LogWriter.Trace(strh, ""); 
        // l(writeToGetTextBoxMsg), new object[] { strh }); 
        if (state != null) 
        { 
         if (state.sb == null) 
          state.sb = new StringBuilder(); 
         state.sb.Length = 0; 
        } 
        //add the rest of the xml 


        string objData = content.Replace("\0", ""); 
        string xmlData = objData.ToString(); 
        try 
        { 


         if (xmlData.Contains("Unsubscribe")) 
         { 
          RemoveSubscriber(xmlData); 
         } 
         else 
         { 
          if (xmlData.Contains("Subscribe")) 
          { 
           if (!state.IsInitiated) 
           { 
            state.Init(); 
            state.socketClient.OnSocketError += new SocketErrorHandler(socketClient_OnSocketError); 
            state.socketClient.clientSocket = handler; 
           } 
           AddSubscriber(xmlData, state); 
          } 

         } 
         xmlData = null; 
         objData = null; 
         content = null; 

        } 
        catch (ArgumentOutOfRangeException ex) 
        { 
         LogWriter.Trace(newAddedStr,"ArgumentOutOfRangeException in ReadCallback"); 
        } 
        catch (Exception ex) 
        { 
         LogWriter.TraceError(ex.Message + " " + ex.StackTrace + " " + newAddedStr); 
        } 
        #region oldCode 

        #endregion 
       } 
       handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(this.ReadCallback), state); 
      } 
     } 
     catch (System.Net.Sockets.SocketException es) 
     { 
      closeSocket(state, false, "Execption:" + es.Message + "," + es.StackTrace); 
      if (es.ErrorCode != 64) 
      { 
       LogWriter.Trace(string.Format("Socket Exception: {0}, {1}.", es.ErrorCode, es.ToString()), ""); 
      } 
     } 
     catch (Exception e) 
     { 
      closeSocket(state, false,"Execption:"+e.Message+","+e.StackTrace); 
      if (e.GetType().FullName != "System.ObjectDisposedException") 
      { 
       Console.WriteLine("Exception: " + e.StackTrace); 
       LogWriter.Trace("Exception Message: " + e.ToString() + e.StackTrace, ""); 
       Console.WriteLine("Exception Message: " + e.ToString()); 
       LogWriter.Trace("ReadCallback:" + e.Message + " " + e.StackTrace, "ERROR"); 
      } 
     } 
    } 

des idées?

+0

Si vous effectuez un netstat sur l'ordinateur serveur * et * l'ordinateur client, la connexion est-elle toujours définie comme établie? – Patrick

+0

Je ne suis pas tout à fait le sens de la réponse. Je suis un peu faible à Netstat. J'ai couru netstat il semble toujours établi. – user437631

+0

Si le client et le serveur sont encore établis, aucun n'a fermé le socket. Êtes-vous complètement sûr que l'un ou l'autre côté effectue réellement une fermeture? – Patrick

Répondre

3

Lorsque vous lisez un socket et que 0 est renvoyé, vous savez que l'autre côté de la connexion est fermé. Est-ce que vous faites ça?

+0

Non, j'ai ajouté mon appel en lecture à la question. Habituellement, je ferme une prise quand le service reste en vie. – user437631

+1

Vous devez fermer la connexion lorsque 0 octet est lu. – jgauffin

+0

Quelle est la signification de la fermeture de la connexion lorsque 0 octets sont lus? pourquoi ne garde pas le serveur en vie? – user437631