Domanda

Ho scritto il mio codice usando questo articolo su msdn come assistente primario

Il mio codice:

    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
        }

    }

Questo è ciò che succede, ho impostato un punto di interruzione su BeginAccept (pensavo che ci fosse il problema), ma lo fa passare normalmente. Tuttavia, quando provo a passare " _AllDone.WaitOne () " - il crash del server.

Se _allDone non può essere utilizzato in un'applicazione per moduli win32 - come posso realizzare il mio progetto?

Modifica

Ho dimenticato di dire che ho scritto _AllDone.Reset () in Accept (), ma non va lì, ho impostato un punto di interruzione lì, ma non andrà.

    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);

    }
È stato utile?

Soluzione

Quindi, se ho capito bene, vuoi riavviare Accept non appena viene ricevuta una connessione socket e non aspettare fino a quando Accept è fatto, e questo è tutto perché non usi la versione di sincronizzazione di Accept .

Quindi stai dicendo che non attiva il tuo metodo Accept quando connetti un socket all'indirizzo e alla porta specificati? Perché è quello che accetta Accetta: accetta una nuova connessione in entrata, in attesa che un client si connetta. Quindi questo potrebbe essere il motivo per cui stai pensando che si è "schiantato" e perché non raggiunge mai il tuo codice nel tuo metodo Accept.

Suggerimento: forse dai un'occhiata anche a Socket.AcceptAsync

Modifica: per configurare un server asincrono in ascolto delle connessioni in entrata, non è necessario alcun 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);
}

Nota: sarà inoltre necessaria una condizione di uscita, in modo che BeginAccept non venga chiamato (ad esempio quando si desidera arrestare il server).

Altri suggerimenti

Penso che Lucero stia cercando di dire che l'applicazione funziona normalmente, potresti chiedere come mai.

Bene, quando si utilizza un'applicazione socket lato server, ciò che sostanzialmente si fa è chiedere al server di collegarsi a una porta e attendere l'arrivo di una connessione. quando arriva la connessione, fai il resto del codice.

Quello che stava dicendo Lucero è che, mentre non arriva alcun messaggio al server, il server continua a restare in attesa, il che potrebbe cercarti come se si congelasse.

È il caso nel tuo codice?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top