0

このトピックについてはあまり見つけることができませんでしたが、最近、SocketAsyncEventArgs オブジェクトを使用してソケット サーバーを実装しています。私は次の例に従いました: Code Project Example

必要に応じてデータ処理クラスを変更しましたが、ソケット処理部分はほとんど触れませんでした。

自分のマシン (win7) でローカルにサービスをテストすると、問題なく動作しているように見えます。Windows Server 2008 で実行する場合も同じです。Windows Server 2008 で実行する場合、メモリ使用量は 50k で推移します (タスク マネージャーから表示)。

.net 4 までのすべての .net アップデート/パッチを含む Windows Server 2003 でサービスを実行すると、次のエラーが表示されます。

Safe handle has been closed
at System.Net.Sockets.Socket.AcceptAsync(SocketAsyncEventArgs e)
at SocketAsyncServer.SocketListener.StartAccept() in 289
at SocketAsyncServer.SocketListener.ProcessAccept(SocketAsyncEventArgs acceptEventArgs)         367
at SocketAsyncServer.SocketListener.AcceptEventArg_Completed(Object sender,    SocketAsyncEventArgs e) in  326
at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e)
at System.Net.Sockets.SocketAsyncEventArgs.ExecutionCallback(Object ignored)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

これに関連するコード行は次のとおりです。行 326

private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
        //Any code that you put in this method will NOT be called if
        //the operation completes synchronously, which will probably happen when
        //there is some kind of socket error. It might be better to put the code
        //in the ProcessAccept method.
        ProcessAccept(e);
}

289行目

bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);

このサーバーは、データ (小さなテレメトリ ペイロード) を送信するために、リモート クライアントから常に接続されています。このサーバーでは、データを解析して応答を返し、ソケットが接続されている間、これを続けます。

私は提案や試してみることにオープンです。もう 1 つの注意事項は、win2k3 でこのサービスを実行すると、サーバー 2008 の 50 ~ 60Kb の範囲に対して、メモリ使用量が 600+Kb に急増し、上記のエラーがスローされることです。

4

1 に答える 1

0

例に提供されたリンクで複数ページのコメントを読んだ後、問題を見つけました。

SocketListener クラスには、次のような「HandleBadAccept」というメソッドがあります。

    private void HandleBadAccept(SocketAsyncEventArgs acceptEventArgs)
    {
        var acceptOpToken = (acceptEventArgs.UserToken as AcceptOpUserToken);
        //This method closes the socket and releases all resources, both
        //managed and unmanaged. It internally calls Dispose.           
        acceptEventArgs.AcceptSocket.Close();

        acceptEventArgs.AcceptSocket = null; //added to handle win2k3 issue

        //Put the SAEA back in the pool.
        poolOfAcceptEventArgs.Push(acceptEventArgs);
    }

私は追加しなければなりませんでした

acceptEventArgs.AcceptSocket = null;

これは現在、Windows 2003 マシンで正常に動作しています。

于 2013-12-05T14:41:29.023 に答える