C #: сбой на ManualResetEvent - PullRequest
       12

C #: сбой на ManualResetEvent

0 голосов
/ 29 апреля 2009

Я написал свой код, используя эту статью в MSDN в качестве основного помощника

Мой код:

    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
        }

    }

Это то, что происходит, я устанавливаю точку останова на BeginAccept (я думал, что есть проблема), но он делает это нормально. Однако когда я пытаюсь выполнить шаг "_AllDone.WaitOne ()" - сбой сервера.

Если _allDone не может быть использован в приложении формы win32 - как мне сделать мой проект?

EDIT

Я забыл упомянуть, что я написал _AllDone.Reset () в Accept (), но он не идет туда, я установил там точку останова, но она не пойдет.

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

    }

Ответы [ 2 ]

1 голос
/ 29 апреля 2009

Так что, если я правильно понял, вы хотите перезапустить Accept, как только будет получено сокетное соединение, а не ждать, пока не будет выполнено Accept, и поэтому вы не используете синхронизирующую версию Accept.

То есть вы говорите, что он не запускает ваш метод Accept, когда вы подключаете сокет к указанному адресу и порту? Потому что это то, что делает Accept: он принимает новое входящее соединение, ожидая подключения клиента. Возможно, именно поэтому вы думаете, что он «потерпел крах» и почему он никогда не достигает вашего кода в вашем методе Accept.

Подсказка: возможно, взгляните также на Socket.AcceptAsync

Редактировать: Чтобы настроить асинхронный сервер, прослушивающий входящие соединения, вам не нужно никакого 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);
}

Примечание: Вам также понадобится условие выхода, чтобы не вызывался BeginAccept (например, когда вы хотите выключить сервер).

0 голосов
/ 21 августа 2009

Я думаю, что Лусеро пытается сказать, что приложение работает нормально, вы можете спросить, как получилось.

Хорошо, когда вы используете приложение сокета на стороне сервера, вы в основном просите сервер liseten к порту и ждете, пока не установится соединение. когда соединение установится, вы делаете оставшуюся часть кода.

Что говорил Лусеро, так это то, что, пока на сервер не поступает сообщение, сервер продолжает зависать и ждать, что может выглядеть так, как будто он завис

Это так в вашем коде?

...