2014-07-15 2 views
2

J'ai un PC client qui m'envoie des données via TCP en utilisant un programme TCP_client que j'ai écrit. Fondamentalement, j'envoie un "Hello Message" au serveur. J'utilise mon PC pour recevoir ces données en utilisant un programme serveur TCP que j'ai écrit.Connexion TCP abandonnée ou impossible de recevoir des données via TCP

class Server 
{ 
    private static TcpListener tcpListener; 
    static System.Timers.Timer aTimer; 
    static int count = 0; 
    public Server() 
    { 
     // 
    } 

    static void Main(string[] args) 
    { 
     tcpListener = new TcpListener(IPAddress.Any, 3000); 
     tcpListener.Start(); 

     aTimer = new System.Timers.Timer(200); 
     aTimer.Elapsed += OnTimedEvent; 
     aTimer.Enabled = true; 


     Console.Read(); 
    } 

    private static void OnTimedEvent(Object source, ElapsedEventArgs e) 
    { 
     TcpClient client = tcpListener.AcceptTcpClient(); 
     Thread.Sleep(2); 
     NetworkStream clientStream = client.GetStream(); 
     Thread.Sleep(2); 

     byte[] message = new byte[4096]; 
     int bytesRead; 

     bytesRead = 0; 

     try 
     { 
      bytesRead = clientStream.Read(message, 0, 4096); 
      client.Close(); 
     } 
     catch (Exception ee) 
     { 
      Console.WriteLine("socket error"); 
      Console.WriteLine(ee.ToString()); 
      client.Close(); 
     } 

     if (bytesRead == 0) 
     { 
      client.Close(); 
     } 
     count++; 

     ASCIIEncoding encoder = new ASCIIEncoding(); 
     Console.WriteLine(count + " " + encoder.GetString(message, 0, bytesRead)); 
    } 

Cela dit, le problème que je vois est que de temps en temps je frapper la « Erreur de socket » dans le Catch() sur mon programme tcp_server.

Erreur:

System.IO.IOException: Unable to read data from the transport connection: An exi 
sting connection was forcibly closed by the remote host. ---> System.Net.Sockets 
.SocketException: An existing connection was forcibly closed by the remote host 
    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, 
SocketFlags socketFlags) 
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s 
ize) 
    --- End of inner exception stack trace --- 
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 s 
ize) 
    at test_tcp_manager.Server.OnTimedEvent(Object source, ElapsedEventArgs e) in 
c:\Users\user\Documents\Visual Studio 2012\Projects\test_tcp_manager\test_tcp_ma 
nager\Program.cs:line 52 

L'erreur se produisent de façon irrégulière pendant une seconde ou quelques secondes. Je voudrais savoir pourquoi et j'aimerais savoir comment y remédier.

U ** PDATE DE SAISIE DE L'UTILISATEUR DE FIX ** premier code Fix de l'utilisateur Usr feed-back:

code tcp_client est ressemble maintenant à ceci:

class Program 
{ 
    const int ourPort = 9090; 
    static IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("172.22.1.22"), 3000); 
    static ASCIIEncoding encoder = new ASCIIEncoding(); 
    static void Main(string[] args) 
    { 
     while (true) 
     { 
      try 
      { 
       using(TcpClient client = new TcpClient()) 
       { 
        client.Connect(serverEndPoint); 
        NetworkStream clientStream = client.GetStream(); 

        byte[] buffer = encoder.GetBytes("Hello Server!"); 

        clientStream.Write(buffer, 0, buffer.Length); 

        client.Close(); 
       } 
      } 
      catch (Exception ee) 
      { 
       Console.WriteLine(ee.ToString()); 
      } 
     } 
    } 
} 

et tcp_server le code est ressemble maintenant à ceci:

class Server 
{ 
    private static TcpListener tcpListener; 
    static int count = 0; 
    public Server() 
    { 
     // 
    } 

    static void Main(string[] args) 
    { 
     tcpListener = new TcpListener(IPAddress.Any, 3000); 
     tcpListener.Start(); 
     while (true) 
     { 
      TcpClient client = tcpListener.AcceptTcpClient(); 
      NetworkStream clientStream = client.GetStream(); 

      byte[] message = new byte[4096]; 
      int bytesRead; 

      bytesRead = 0; 

      try 
      { 
       bytesRead = clientStream.Read(message, 0, 4096); 
      } 
      catch (Exception ee) 
      { 
       Console.WriteLine("Socket rror"); 
       Console.WriteLine(ee.ToString()); 
      } 
      count++; 

      ASCIIEncoding encoder = new ASCIIEncoding(); 
      Console.WriteLine(count + " " + encoder.GetString(message, 0, bytesRead)); 
     } 
    } 
} 

Répondre

1
  1. ne pas oublier de cl ose le client après avoir envoyé votre message. La connexion persistera jusqu'à ce que le GC décide de l'éteindre.
  2. Le vidage d'un réseau ne fait rien. Ne soyez pas superstitieux et tout rincer parce qu'il semble plus sûr.
  3. Vous acceptez une temporisation. Je n'ai jamais vu ce genre d'erreur avant. Pourquoi faites-vous cela? Vous devriez accepter dans une boucle tous les clients qui se connectent, et les servir indépendamment. Pourquoi restreignez-vous le serveur à un client par tick?
  4. Retirez le sommeil. Chaque fois que vous pensez que vous avez besoin de dormir, pensez plus fort.
  5. Vous supposez que vous allez lire un "message" lors de la première lecture. Lire vous renvoie au moins un octet. Cela ne garantit rien d'autre. TCP n'a pas de message. Assurez-vous que votre code peut gérer la réception de données entrantes par octet.
  6. Utilisez l'instruction using pour toutes les ressources jetables et débarrassez-vous de tous ces appels Close Close.

De nombreux problèmes. La programmation de la prise est difficile. Soyez très prudent.

+0

@ usr je mis à jour le code ci-dessus, est-ce match avec ce que vous suggérez? – user3573417

+0

C'est un bon progrès! (5) n'est toujours pas résolu. C'est un bug latent que vous ne remarquez pas pour les petites tailles de message. Vous devez également fermer 'client' sur le serveur lorsque vous avez terminé de traiter ce client. – usr

+0

comment puis-je corriger 5? Je ne comprends pas cette partie. je voudrais juste utiliser un tampon de taille plus grande? – user3573417