Question

J'ai écrit mon code en utilisant cet article dans msdn en tant que assistant principal

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. J’ai défini un point d’arrêt sur BeginAccept (je pensais que c’était le problème), mais il y réagit normalement. - le crash du serveur.

Si _allDone ne peut pas être utilisé dans une application de formulaire Win32, comment puis-je créer mon projet?

MODIFIER

J'ai oublié de mentionner que j'ai écrit _AllDone.Reset () dans Accept (), mais cela ne va pas là-bas, j'ai défini un point d'arrêt là-bas, mais ça 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);

    }
Était-ce utile?

La solution

Donc, si je comprends bien, vous voulez redémarrer Accepter dès qu'une connexion de socket est reçue et ne pas attendre que Accepter soit terminé. pourquoi vous n'utilisez pas la version de synchronisation de Accepter .

Vous dites donc que la méthode Accept n’est pas déclenchée lorsque vous connectez un socket à l’adresse et au port spécifiés? En effet, c’est ce que fait Accept: accepter une nouvelle connexion entrante en attendant la connexion d’un client. C’est peut-être pour cette raison que vous pensez que le message "s'est écrasé". et pourquoi il n'atteint jamais votre code dans votre méthode Accept.

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

Modifier: Pour configurer un serveur asynchrone écoutant les connexions entrantes, vous n'avez pas besoin de 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);
}

Remarque: vous aurez également besoin d'une condition de sortie afin que BeginAccept ne soit pas appelé (par exemple lorsque vous souhaitez arrêter le serveur).

Autres conseils

Je pense que Lucero essaie de dire que l'application fonctionne normalement, vous pouvez vous demander pourquoi.

Lorsque vous utilisez une application de socket côté serveur, vous devez essentiellement demander au serveur de se connecter à un port et d’attendre la connexion. quand la connexion arrive, vous faites le reste du code.

Ce que Lucero disait, c’est que, même si aucun message n’arrive sur le serveur, le serveur continue à écouter et à attendre, ce qui pourrait vous chercher comme s’il se figeait.

Est-ce le cas dans votre code?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top