1

初めての投稿なのでお手柔らかにお願いします(=_=)

私は自分のオフィスの DB を管理するための非同期サーバー/クライアント アプリケーションを作成しています。自分のコンピューターでローカルにテストしたところ、問題なく動作しました。サーバーツールを別のマシンにアップロードしたとき、気が狂いそうなものを見つけました。サーバー/クライアントは最初のクエリのみを処理し、別のクエリを送信すると、サーバーとクライアントの両方がクラッシュします。

デバッグモードで行を調べた後、私は問題を発見しました.beginconnect()の後(2番目のクエリ中)、ソケットは接続されていますが、デバッガがbeginsend()行に到達するとソケットが切断されます(これはクライアント側でのみ発生し、サーバー側のソケットが接続されているようです)。

ソケットは、新しいクエリを送信するたびに再インスタンス化され、もちろん、クエリ プロセス (送信/受信) が完了した後にシャットダウンされて破棄されます。私の考えでは、ソケットの破棄はすぐには行われず、しばらくしてから行われます (しかし、なぜ常に新しい beginconnect() と beginend() の間で行われるのでしょうか?)。これについて手がかりはありますか?または、精神病院の部屋を予約する必要がありますか?

* 新しい部分 (編集) *

うーん..ここでまた!今回は、クライアント側のソケットはセッション全体で開いたままです (ソケットの閉鎖はクライアント ツールの閉鎖時にのみ発生します) が、別の種類のエラーが表示されます: "System.Net.Sockets.SocketException (0x80004005): 既存の接続がによって強制的に閉じられましたSystem.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) のリモート ホスト"この接続閉鎖コマンドがどこにあるかを示す行。問題は次のコードにある可能性があることがわかりました。

    private static void SendCallback(IAsyncResult ar)
    {
        Console.WriteLine("send callback");
        try
        {
            // Retrieve the socket from the state object.
            Socket handler = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.
            int bytesSent = handler.EndSend(ar);
            Console.WriteLine("\nQuery answer sent to client");

            handler.Shutdown(SocketShutdown.Both);
            //handler.Disconnect(true);
            //handler.Dispose();
            state.content = new List<byte[]>();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
            Console.ReadKey();
        }
    }

handler.shutdown 行を削除すると、クライアントは送信の終了を検出できなくなります (実際の問題ではなく、送信されたパケットの最後の部分であるため、それをトリガーとして使用することができます..少なくとも私は思います)。なにか提案を?キープアライブについて何か読んだことがありますが、それを設定する方法と、この状況で本当に必要かどうかがわかりません。よろしくお願いいたします。

4

1 に答える 1

0

あなたのようにソケットを開閉しないことをお勧めします。
プログラムと OS によって解放される必要があるため、可能であればソケットを開いたままにします。

于 2013-01-31T16:39:19.610 に答える