2009-04-29 9 views
0

J'ai écrit mon code à l'aide this article at msdn comme aide primaireC#: Crash on ManualResetEvent

Mon code:

private ManualResetEvent _AllDone = new ManualResetEvent(false); 

    internal void Initialize(int port,string IP) 
    { 
     IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port); 
     Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     _Accpt.Bind(_Point); 
     _Accpt.Listen(2); 

     while (true) 
     { 
      _AllDone.Reset(); 
      _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt); 
      _AllDone.WaitOne(); <<crash here 
     } 

    } 

C'est ce qui se passe, je mis un point d'arrêt à BeginAccept (je pensais il y a le problème) , mais il marche normalement.Cependant, quand j'essaie de faire "_AllDone.WaitOne()" - le plantage du serveur.

Si _allDone ne peut pas être utilisé dans une application win32 - comment créer mon projet?

EDIT

J'ai oublié de mentionner que j'écrit _AllDone.Reset() dans accept(), mais il ne va pas là, je mets un point d'arrêt là-bas, mais il ne va pas.

private void Accept(IAsyncResult async) 
    { 
     _AllDone.Set(); 
     Socket _Accpt = (Socket)async.AsyncState; 
     Socket _Handler = _Accpt.EndAccept(async); 

     StateObject _State = new StateObject(); 
     _State.workSocket = _Handler; 

     _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State); 

    } 
+0

les détails de l'exception aideraient – Crippledsmurf

+0

Il n'y a aucune exception, il se bloque seulement (crash). –

+0

Quel genre de "serveur" est-ce? Un service Windows, ou juste une application de console agissant comme un serveur pour tester? –

Répondre

1

Donc, si je comprends bien, vous voulez redémarrer Accept dès qu'une connexion socket est reçue, et ne pas attendre jusqu'à ce que Accept est fait, et c'est pourquoi ne pas utiliser la version de synchronisation de Accept.

Vous dites donc que votre méthode Accept n'est pas déclenchée lorsque vous connectez une socket à l'adresse et au port spécifiés? Parce que c'est ce que fait Accept: il accepte une nouvelle connexion entrante, attendant qu'un client se connecte. C'est peut-être la raison pour laquelle vous pensez qu'il a "planté" et pourquoi il n'atteint jamais votre code dans votre méthode Accept.

Astuce: peut-être aussi un oeil à Socket.AcceptAsync

Edit: Pour configurer un serveur async écoutant les connexions entrantes, vous n'avez pas besoin ManualWaitEvent:

internal void Initialize(int port,string IP) { 
    IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port); 
    Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    _Accpt.Bind(_Point); 
    _Accpt.Listen(2); 
    _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt); 
} 

private void Accept(IAsyncResult async) { 
    Socket _Accpt = (Socket)async.AsyncState; 
    Socket _Handler; 
    try { 
     _Handler = _Accpt.EndAccept(async); 
    } finally { 
     _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt); 
    } 

    StateObject _State = new StateObject(); 
    _State.workSocket = _Handler; 

    _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State); 
} 

Note: Vous aurez également besoin d'une condition de sortie, de sorte que BeginAccept n'est pas appelé (par exemple lorsque vous souhaitez arrêter le serveur).

+0

Votre première déclaration est juste - c'est ce que je veux. Toutefois, votre deuxième instruction est erronée. Je ne me suis pas connecté avec un client TCP. J'appelle simplement ce code pour configurer le serveur. –

+0

Eh bien, donc rien ne s'est écrasé jusqu'à présent.Le serveur attend une connexion client entrante et appellera uniquement votre méthode Accept lors de la réception d'une telle connexion. – Lucero

+0

Je pense que vous vous méprenez sur mon problème. Comment puis-je faire attendre sans crash? –

0

Je pense que Lucero essaie de dire, que l'application fonctionne normalement, vous pouvez demander comment venir. Lorsque vous utilisez une application de socket côté serveur, vous demandez au serveur de se connecter à un port et d'attendre l'arrivée d'une connexion. Lorsque la connexion arrive, vous faites le reste du code. Ce que disait Lucero, c'est que pendant qu'aucun message n'arrive sur le serveur, le serveur continue à émettre et à attendre, ce qui peut vous sembler bloqué.

Est-ce le cas dans votre code?