2009-11-08 5 views
4

J'ai un programme en C# dans lequel je crée un socket, je le lie, je commence à écouter puis j'utilise beginaccept! mais quand j'essaye de fermer \ shutdown le socket j'obtiens des exceptions de la méthode de beginaccept AsyncCallback!Impossible de fermer le socket après la méthode BeginAccept

 private void start_listening() 
     { 

      main_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      IPEndPoint iplocal = new IPEndPoint(IPAddress.Any, 11150); 
      main_socket.Bind(iplocal); 
      main_socket.Listen(5); 
      main_socket.BeginAccept(new AsyncCallback(OnClientConnect), null); 
      } 


     private void Disconnect_Click(object sender, EventArgs e) 
     { 
      main_socket.Shutdown(SocketShutdown.Both); 
      main_socket.Close(); 
     } 

     public void OnClientConnect(IAsyncResult asyn) 
     { 

      try 
      { 
       clients[connected_clients] = new Client("CHANGEME", "127.0.0.1", this); 
       clients[connected_clients].Socket = main_socket.EndAccept(asyn); 
       clients[connected_clients].WaitForData(); 
       main_socket.BeginAccept(OnClientConnect, null); 
      } 
      catch (SocketException se) 
      { 
       MessageBox.Show(se.Message); 
      } 
} 

merci beaucoup!

Répondre

6

Lorsque main_socket est fermé, OnClientConnect() sera appelé mais main_socket.EndAccept() est supposé lancer une exception ObjectDisposedException. Peut-être souhaitez-vous capturer cette exception et la traiter comme un message "Le socket de l'écouteur a été fermé".

L'autre problème avec votre code est que main_socket n'est réellement connecté à rien. Appeler main_socket.Shutdown() dans Disconnect_Click() peut aussi lancer, mais cette fois, il devrait s'agir d'une exception SocketException disant que le socket n'est pas connecté. Je supprimerais cet appel main_socket.Shutdown().

+2

+1. Malheureusement, il n'y a pas de propriétés telles que "IsClosed". Socket vient du monde sombre et non géré de Cthulhu. – Roubachof

+1

En fait, il existe un moyen: Socket.Handle sera -1 si le socket a été fermé dans le côté local de la connexion. – Gonzalo

+0

merci les gars pour les réponses! Je vais vérifier ça. alors vous dites que quand je me suis jeté dans onclientconnect parce que la prise est fermée je devrais gérer cette excaption? – Hipno

0

« Pour annuler un appel en attente à la méthode BeginAccept, fermer le socket. Lorsque la méthode Close est appelée alors qu'une opération asynchrone est en cours, le rappel fourni à la méthode BeginAccept est appelée. Un appel après la La méthode EndAccept lève une ObjectDisposException pour indiquer que l'opération a été annulée. "

Socket.BeginAccept Method (AsyncCallback, Object)

manière appropriée pourrait être:
1) créer socket client au serveur, connectez à la prise d'écoute, après avoir EndAccept réussi fermer
2) de la manière suggérée par MSDN est juste pour gérer cette exception est

1

Ancien sujet, mais une solution est: Gardez une variable locale, pour garder une trace de quand vous "fermez/éteignez" le socket. J'utilise _isShutdown. Lorsque vous commencez à écouter sur le socket, définissez _isShutDown = False;
Avant de fermer la prise, set _isShutdown = True;

Dans la fonction EndAccept(iar), seul appel

socket.EndAccept() when _isShutdown is false 
<pre><code> 
if (_isShutdown == false) 
{ 
someWorkSocket = listenSocket.EndAccept(iaSyncResult); 
//... 
} 
else 
{ 
//socket is closed, and we shouldn't use it. Should erase this else clause.. 
} 

Questions connexes