web-dev-qa-db-ja.com

BufferedReader readLine()ブロック

ReadLine()を使用してデータを受信するとき、メッセージの送信時に.flushを使用してメッセージの最後に「\ n」を付けても、メッセージを読み取るwhileループがブロックされます。ソケット接続を閉じるときにのみ、ループから抜けます。

これがクライアントコードです:

bos = new BufferedOutputStream(socket.
            getOutputStream());
bis = new BufferedInputStream(socket.
            getInputStream());
osw = new OutputStreamWriter(bos, "UTF-8");
osw.write(REG_CMD + "\n");
osw.flush();

isr = new InputStreamReader(bis, "UTF-8");
BufferedReader br = new BufferedReader(isr);

String response = "";
String line;

while((line = br.readLine()) != null){
   response += line;
}

そしてサーバーのコード:

BufferedInputStream is;
BufferedOutputStream os;

is = new BufferedInputStream(connection.getInputStream());
os = new BufferedOutputStream(connection.getOutputStream());

isr = new InputStreamReader(is);

String query= "";
String line;

while((line = br.readLine()) != null){
   query+= line;
}

String response = executeMyQuery(query);
osw = new OutputStreamWriter(os, "UTF-8");

osw.write(returnCode + "\n");
osw.flush();

コードがサーバーのwhileループでブロックされます。ありがとう。

11
Majid

BufferedReaderは、最後(ファイルの終わり、ストリーム、ソースなど)に到達するまで入力の読み取りを続けます。この場合、「終了」はソケットのクローズです。したがって、ソケット接続が開いている限り、ループが実行され、BufferedReaderはさらに入力を待機し、 '\ n'に到達するたびにループします。

14
Sinkingpoint

これは、whileループの条件が原因です:while((line = br.readLine()) != null)

すべての反復で行を読み取り、readLineがnullを返した場合はループを終了します。

readLineは、eof(= sockedが閉じられている)に達した場合はnullのみを返し、 '\ n'が読み取られた場合はStringを返します。

readLineでループを終了する場合は、whileループ全体を省略できます。

line = br.readLine()

3
cIph3r

私はたくさんの解決策を試しましたが、実行をブロックしていないのは私が見つけた唯一のものでした:

_BufferedReader inStream = new BufferedReader(new 
InputStreamReader(yourInputStream));
String line;
while(inStream.ready() && (line = inStream.readLine()) != null) {
    System.out.println(line);
}
_

次のinStream.ready()呼び出しが実行をブロックする場合、readLine()はfalseを返します。

3
vovahost

これは、InputStreamが赤になる準備ができていないために発生し、in.readLine()でブロックされます。これを試してください:

boolean exitCondition= false;

while(!exitCondition){
    if(in.ready()){
        if((line=in.readLine())!=null){
            // do whatever you like with the line
        }
    }
}

もちろん、exitConditionを制御する必要があります。

他のオプションは、非同期(ブロックではなく)読み取りを可能にするnioパッケージの使用ですが、それはユーザーのニーズに依存します。

1
Mehdi

readline()とread()は、ソケットが閉じていない間はブロックされます。だからあなたはソケットを閉じるべきです:

Socket.shutdownInput();//after reader
Socket.shutdownOutput();//after wirite

socket.close();ではなく

0
Ado

ソケットを強制的に閉じずにソケットにあるものを取得したい場合は、単にObjectInputStreamとObjectOutputStreamを使用します。

例:

ObjectInputStream ois;
ObjectOutputStream oos;

ois = new ObjectInputStream(connection.getInputStream());

String dataIn = ois.readUTF(); //or dataIn = (String)ois.readObject();

oos = new ObjectOutputStream(connection.getOutputStream());
oos.writeUtf("some message"); //or use oos.writeObject("some message");
oos.flush();

.....
0
OmarSSelim