質問

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にブレークポイントを設定しました(問題があると思っていました)が、通常どおりステップします。しかし、&quot; _AllDone.WaitOne()&quot; -サーバーがクラッシュします。

_allDoneをwin32フォームアプリケーションで使用できない場合-プロジェクトの作成方法

編集

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

    }
役に立ちましたか?

解決

そのため、正しい場合は、ソケット接続が受信されるとすぐに 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が呼び出されません(たとえば、サーバーをシャットダウンする場合)。

他のヒント

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

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

Luceroが言っていたのは、サーバーにメッセージが届かない間、サーバーは設定と待機を続けているため、フリーズしたかのように見えるかもしれません。

コードの場合ですか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top