2

私は単純なJavaサーバーソケットを持っていますが、C#.Netソケットで接続してJavaソケットに送信すると、ブロックされ、ブロックを停止するために.Netソケット送信をシャットダウンする必要があります。これは、通信のたびにソケットを閉じる必要があることを意味します。どこが間違っているのですか?

socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint ip = new IPEndPoint(IPAddress.Parse(ipAddress.Text), 8089);
                socket.Connect(ip);
 byte[] b = Encoding.UTF8.GetBytes(json);
            socket.Send(b, b.Length, SocketFlags.None);
        socket.Shutdown(SocketShutdown.Send);
        int timeout = 0;
        while (socket.Available == 0)
        {
            Thread.Sleep(100);
            timeout++;
        }


        string response = "";
        byte[] buffer = new byte[8192];
        int total = 0;
        while (socket.Available > 0)
        {
            int len = socket.Receive(buffer);
            total += len;
            response = response + (Encoding.UTF8.GetString(buffer, 0, len));
            buffer = new byte[1024];
            if (socket.Available == 0) Thread.Sleep(250);
        }
        MessageBox.Show(response);
        return response.Trim();

    }

サーバ側

clientSocket = serverSocket.accept();
        clientSocket.setKeepAlive(true);
        Log.d("DbThread","client Connected");

        br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()),8192);
        bo = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()),8192);

        Thread.sleep(100);
        char[] buffer = new char[8192];

        int len=0;
        String build = "";
        while((len = br.read(buffer))>0){

            build = build + new String(buffer);
            buffer = new char[8192];
        }

        JSONObject json = new JSONObject(build.trim());
        Log.d("input",build.trim());
        String output = "";
        Gson gson = new Gson();
        switch(json.getString("classType").charAt(0))
        {
        case 'Q':
            Log.d("classType","Q");
            Query query = gson.fromJson(build.trim(), Query.class);
            output = query.executeToJson();Log.d("Query","end");break;

        case 'I':
            Log.d("classType","I");
            Insert insert = gson.fromJson(build.trim(), Insert.class);
            output = insert.executeToJson();break;

        case 'U':
            Log.d("classType","U");
            Update update = gson.fromJson(build.trim(), Update.class);
            output = update.executeToJson();break;

        case 'D':
            Log.d("classType","D");
            Delete delete = gson.fromJson(build.trim(), Delete.class);
            output = delete.executeToJson();break;

        }       



        bo.write(output);
        bo.flush();

        Log.d("Query",output);

    br.close();
4

1 に答える 1

1

まず、Availableループの終了条件が安全でないことを確認します。これは、ローカルでバッファリングされるものだけを示しています。それはストリームの終わりとは何の関係もありません。

次に、aを追加することThread.Sleepは、これを行うための理想的な方法ではありません。読むか受け取るだけ。一部のデータが利用可能になるまでブロックされます。通常、読み取りまたは受信をループするだけです。

ハングする明らかな条件の1つは、他のマシンが応答を送信していない場合です。その場合、それは最上位のループに永久に留まります。

その他の注意事項:

  • 反復ごとに新しいものを割り当てる必要はありませんbuffer以前の8192バッファはまだ問題ありません。再利用
  • 特にUTF8を使用しているため、バッファに文字全体が含まれていると想定しないでください。バッファには、文字のマルチバイト表現の一部を含めることができます。通常、デコードを開始する前に、メッセージ/フレーム全体があることを確認する方が簡単です。

個人的には、多くのデバッグ出力とネットワークスニファを追加してこれを調査します。

于 2012-08-02T14:07:26.367 に答える