2010-11-30 3 views
2

J'écris une petite application C# Sockets. En fait j'en ai deux, un serveur et un client.Commencer à écouter à nouveau avec Socket après une déconnexion

L'utilisateur exécute le client, saisit l'adresse IP et le port du serveur, appuie sur 'connexion', puis une fois connecté, il peut entrer du texte dans une zone de texte et l'envoyer au serveur.

Le serveur affiche simplement "Pas de connexion" ou "Connexion depuis [ip]: [port]" et le message reçu le plus récent en dessous.

Le serveur reçoit avec succès les messages et gère même la déconnexion du client. Maintenant j'essaie de le faire réécouter après que le client se soit déconnecté mais pour une raison quelconque, rien que j'essaie lui permettra de recommencer à écouter.

Voici une partie de mon code:

Socket socket; 
    private void listen() 
    { 
     socket = new Socket(AddressFamily.InterNetwork, 
      SocketType.Stream, ProtocolType.Tcp); 
     socket.Bind(new IPEndPoint(IPAddress.Any, 12345)); 
     socket.Listen(10); 
     socket.BeginAccept(new AsyncCallback(acceptAsync), socket); 
    } 

et

private void receiveAsync(IAsyncResult res) 
    { 
     Socket socket = (Socket)res.AsyncState; 

     try 
     { 
      int nBytes = socket.EndReceive(res); 
      if (nBytes > 0) 
      { 
       Invoke(new MethodInvoker(delegate() 
       { 
        lMessage.Text = encoder.GetString(buffer); 
       })); 
       setupReceiveAsync(socket); 
      } 
      else 
      { 
       Invoke(new MethodInvoker(delegate() 
       { 
        lConnections.Text = "No Connections."; 
        lMessage.Text = "No Messages."; 
        socket.Shutdown(SocketShutdown.Both); 
        socket.Close(); 
        listen(); 
       })); 
      } 
     } 
     catch { } 
    } 

La dernière ligne: écouter(); est ce qui jette l'erreur. J'ai essayé à nouveau d'appeler socket.BeginAccept(), mais cela déclenche également une exception.

Le message que je reçois est:

Une seule utilisation de chaque adresse de socket (protocole/adresse réseau/port) est normalement autorisé

Si je n'appelle mon écouter() fonction et à la place juste appeler socket.BeginAccept(), puis je reçois "Vous devez d'abord appeler socket.listen()"

Si j'appelle la fonction socket.listen(), alors il me dit qu'il est déjà connecté et Le chariot commence à écouter.

Une fois que j'ai établi une connexion asynchrone et reçu plusieurs messages asynchrones, comment puis-je recommencer à recevoir?

+0

Veuillez poster plus de votre code. On dirait que vous jetez la prise d'écoute sans la jeter correctement, et qu'elle n'a pas encore été ramassée, donc le port est toujours ouvert par elle. – cdhowie

+0

Où appelez-vous 'EndAccept' à? – Donnie

Répondre

2

Votre variable socket est déjà associée à une prise d'écoute la deuxième fois que vous appelez listen(), ce qui explique pourquoi une seule utilisation est autorisée. Tout ce que vous devez répéter est l'appel socket.BeginAccept(new AsyncCallback(acceptAsync), socket). Essayez donc de remplacer l'appel par listen() dans votre méthode receiveAsync(...) par socket.BeginAccept(new AsyncCallback(acceptAsync), socket).

+0

a résolu mon problème. – msuhash

2

Dans asyncBegin* est toujours suivi de End*. Voir Utilisation d'un Asynchronous Server Socket. Votre méthode accept doit être quelque chose comme:

try { 
     listener.Bind(localEP); 
     listener.Listen(10); 

     while (true) { 
      allDone.Reset(); 

      Console.WriteLine("Waiting for a connection..."); 
      listener.BeginAccept(
       new AsyncCallback(SocketListener.acceptCallback), 
       listener); 

      allDone.WaitOne(); 
     } 
    } catch (Exception e) { 

Server, signifie qu'une application qui écoute sur le port/IP spécifiée. Est généralement, toujours dans un mode d'écoute - c'est pourquoi il est appelé un serveur. Il peut se connecter et déconnecter un client, mais est toujours en mode écoute. Cela signifie qu'un serveur déconnecte un client - même alors - il est en mode d'écoute; ce qui signifie qu'il peut également accepter les connexions entrantes.Cependant, la demande de déconnexion peut provenir du client ou peut être appliquée de force par le serveur.

Procédé pour un serveur est:

  1. Bind à douille
  2. Écouter
  3. accepter les connexions

Le processus de client est:

  1. Connect au serveur
  2. Envoyer/recevoir des messages

Il y a plusieurs façons pour le serveur pour gérer les clients entrants, en couple, comme suit:

  • Les connexions entrantes sont conservées dans une liste, par exemple dans un List<TcpClient>.
  • Une façon de gérer les clients entrants est à travers les threads. Par exemple, pour chaque client entrant, générer un thread qui gérerait la communication entre le serveur et le client. Par exemple, checkout this example.

_

private void ListenForClients() 
{ 
    this.tcpListener.Start(); 

    while (true) 
    { 
    //blocks until a client has connected to the server 
    TcpClient client = this.tcpListener.AcceptTcpClient(); 

    //create a thread to handle communication 
    //with connected client 
    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); 
    clientThread.Start(client); 
    } 
} 
  • usage unique fil et contexte d'utilisation de commutation pour gérer les communications client (TX/RX).
Questions connexes