2

作成したアプリに問題があります。一般的な状況 (次の説明は質問に関連する 1-1 ではありません): 複数のサイトでデータを収集するための WCF クライアント サーバー アプリがあります。クライアントはローカル データ (いくつかのファイルなど) を取得し、それをデータセンター内のサーバーに送信し、このサーバーが処理します。クライアントはローカルホストからほとんどのデータを取得しますが、一部は LAN 上の別のサーバーから取得されます。ここから私の問題が始まります。指定されたクライアントにデータを送信する 3 番目のアプリを作成する必要がありました。この投稿のリマインダーとして、クライアントとサーバーを同じ LAN 上のアプリと呼んでいます (上のデータセンターのサーバーではありません)。

名前付きパイプを使用してみました。これは、同じホスト上で優れたインタープロセスを実行しましたが、サーバー間の速度が非常に遅かったです。(誰かがこれがなぜなのかについて考えている場合は、遠慮なく教えてください。一部のテストでは、数バイトの送受信で最大 1000 ミリ秒になりました)

そこで、TcpClient クラスを使用することにしました。テストでは、同等の NP よりもはるかに高速な応答が示されたので、このオプションを使用することにしました。

これで、クライアントとサーバーの両方が想定どおりに開始および終了すると、すべて問題ありません。サーバーが起動され、クライアントが接続され、サーバーがその stream.Read() メソッドを待機しているときに問題が発生し、クライアント アプリが終了します。

Unable to read data from the transport connection: De externe host heeft een verbinding verbroken.(第 2 部の翻訳: 既存の接続がリモート ホストによって強制的に閉じられました。)

現時点では、Try-Catch ステートメントで全体をラップし、IoException で全体を再起動しました。これはうまくいきますが、「例外は例外的なものであるべきです!」に関するいくつかの投稿を読むと、気分が悪くなります。

最後に質問: この例外をどのように回避できますか? (実際にサーバーとクライアント アプリ間の接続を維持する通常の方法は何ですか?)

サーバー TcpListener serverSocket = 新しい TcpListener(System.Net.IPAddress.Any, 8888); TcpClient clientSocket = default(TcpClient);

        while (true)
        {
            serverSocket.Start();
            clientSocket = serverSocket.AcceptTcpClient();

            while ((true))
            {
                try
                {
                    NetworkStream networkStream = clientSocket.GetStream();
                    byte[] bytesFrom = new byte[10025];
                    networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);//THIS THROWS THE EXCEPTION WHEN A CLIENT QUITS
                    string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
                    Console.WriteLine(" >> Data from client - " + dataFromClient);
                    string serverResponse = "Server response " + DateTime.Now.ToString("HH:mm:ss,fff");
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);

                    int len = sendBytes.Length;
                    networkStream.WriteByte((byte)(len / 256));
                    networkStream.WriteByte((byte)(len & 255));

                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                }
                catch (System.IO.IOException ex)
                {
                    Console.WriteLine(ex.ToString());
                    break;
                }

            }
            clientSocket.Close();
            serverSocket.Stop();
        }
    }

クライアント

System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();


    private void button2_Click(object sender, EventArgs e)
    {
        NetworkStream serverStream = clientSocket.GetStream();
        byte[] outStream = System.Text.Encoding.ASCII.GetBytes("Message from Client$");
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();
        int len = serverStream.ReadByte() * 256;
        len += serverStream.ReadByte();

        byte[] inStream = new byte[len];
        serverStream.Read(inStream, 0, len);
        string returndata = System.Text.Encoding.ASCII.GetString(inStream);
        msg("Data from Server : " + returndata);
    }

    private void button1_Click_1(object sender, EventArgs e)
    {
        clientSocket.Connect("127.0.0.1", 8888);
    }
4

2 に答える 2

0

このエラーにはいくつかの原因がありますが、最も一般的なのは、相手側で既に閉じられている接続に書き込んだことです。つまり、アプリケーション プロトコル エラー: 決して消費できない状況で何かを書きました。

両端を書いた場合の別のやや遠い可能性は、何らかの理由でクライアントを異常終了するようにコーディングしたことです。基本的に絶対にやってはいけないことです。

于 2013-01-27T23:17:02.933 に答える