0

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()」をステップしようとすると-サーバーがクラッシュします。

win32 フォーム アプリケーションで _allDone を使用できない場合 - プロジェクトを作成するにはどうすればよいですか?

編集

Accept() に _AllDone.Reset() を書いたことを忘れていましたが、そこには行きません。そこにブレークポイントを設定しましたが、行きません。

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

    }
4

2 に答える 2

1

したがって、私が正しく理解できれば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 が呼び出されないように、終了条件も必要になります (たとえば、サーバーをシャットダウンする場合)。

于 2009-04-29T14:55:37.043 に答える
0

Lucero は、アプリケーションが正常に動作することを言おうとしていると思います。

サーバー側のソケット アプリケーションを使用している場合、基本的に行うことは、サーバーにポートをリッスンするように要求し、接続が到着するのを待つことです。接続が到着したら、残りのコードを実行します。

Lucero が言っていたことは、メッセージがサーバーに到着しない間、サーバーは待機し続け、フリーズしたかのようにあなたを探すかもし​​れないということです。

あなたのコードではそうですか?

于 2009-08-21T17:15:32.660 に答える