3

私はJavaソケットにかなり慣れていないので、同じソケットを使用してデータを送受信するのに問題があります。

サーバーは Android デバイス上にあります。

    ServerSocket listenSocket = null;
    OutputStream dataOutStream = null;
    Socket socket = null;
    InputStream dataInputStream = null;

    // Listen
    System.out.println("Start listening");
    try {
        listenSocket = new ServerSocket(4370);
        socket = listenSocket.accept();
        System.out.println("Connection accepted");
        dataInputStream = socket.getInputStream();
        dataOutStream = socket.getOutputStream();
        while (dataInputStream.read() != -1);
    } catch (IOException e) {
        e.printStackTrace();
        close(listenSocket, socket);
        return;
    }

    // Answer
    System.out.println("Answering...");
    byte[] answer = {(byte) 0x82, (byte) 0xf8, 0, 0};
    try {
        dataOutStream.write(answer);
    } catch (IOException e) {
        e.printStackTrace();
        close(listenSocket, socket);
        return;
    }

    close(listenSocket, socket);
    System.out.println("Finished");

クライアントは、Java 6 を搭載した Linux マシンで実行されます。

    Socket socket = new Socket("192.168.1.33", 4370);
    OutputStream dataOutputStream = socket.getOutputStream();
    InputStream dataInputStream = socket.getInputStream();
    byte[] bufferOut = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    dataOutputStream.write(bufferOut);
    System.out.println("Sent");

    while (dataInputStream.read() != -1);       
    socket.close();
    System.out.println("Finished");

ここでの問題は、サーバーがwhile (dataInputStream.read() != -1);回線にスタックすることです。クライアントが送信を閉じないように見えます。

私がdataOutputStream.close()クライアント部分で行うと(もちろん、書いた後)、それは機能しますが、クライアントwhile (dataInputStream.read() != -1);はソケットが閉じられたと言って死んでしまいます。

閉じるコマンドが送信されるまで、この同じソケットを介してより多くのデータ交換を行うために、ソケット全体を開いたままにします。

私は明らかにここで何か間違ったことをしています、何か洞察はありますか? 前もって感謝します!

4

3 に答える 3

12

You neither close the socket nor the outputstream. You do a shutdownOutput() in the client side:

...
dataOutputStream.write(bufferOut);
System.out.println("Sent");
socket.shutdownOutput();
...

This is called a half close, since it closes only one direction and leaves the other direction open.

于 2012-10-15T17:00:22.637 に答える
2

編集: Olaf は、質問で要求応答シナリオを実現する組み込みの方法を示しました。

ソケットから取得したストリームを閉じると、ソケットも閉じられます (も参照)。一方、ソケットから取得した InputStream は、ストリーム/ソケットが開いている限り、すべてのデータが送信されたかどうかを確認することはできません (途中でより多くのビットになります!)。Olafs の例を使用しない限り、双方向通信はこの方法では機能しません。これにより、サーバーの応答を待つことができます。

あなたができることは、エンドシグナルを自分で定義することです(たとえば、文字列「END」)。どちらの側も、そのエンドシグナルが読み取られるまでリッスンし、次に書き込みます。しかし、それには確実に遭遇する他のあらゆる種類の問題が伴います (送信されたテキストに終了信号が含まれている場合はどうなりますか? 終了を送信する前にパートナーが死亡した場合はどうなりますか? タイムアウト?...)。こちらもご覧ください

Java で十分にサポートされている SOAP または RESTful サービスを調べてみます (ただし、Android でどの程度サポートされているかはわかりません)。一般に、これらの問題に対処し、低レベルのネットワーキングから解放する多くのライブラリがあります。ほとんどの場合、既存のソリューションを使用することで成果が得られます。

于 2012-10-15T16:53:12.890 に答える
0

実行して OutputStream をフラッシュしてみてくださいdataOutStream.flush()

于 2012-10-15T16:52:02.060 に答える