2017-10-08 21 views
0

完全に透過的であるように、これは割り当て用です。ソケットのバッファ付きリーダーは決して準備ができていません

ありやるべきことがあるが、現時点では、私はちょうど次を取得しようとしている:

  1. ノードAはノードAがテキストファイル(マイナス最初に送信し
  2. テキストファイルから読み込みますノードBは、ソケットは、前記今、情報が送信されていないのいずれかと思われる。しかし、コンソールに

それをプリントアウト、またはから読み込まソケット

  • を使用してノードBへの線)それは対応していないCTLY私のメインクラス内のノードB.

    ことで、私はこのようなノードを設定します。

    //Open a socket for talking with NodeB 
    Socket mySocket = new Socket(InetAddress.getLocalHost(), portNum); 
    
    //Set up the socket's output 
    PrintWriter out = new PrintWriter(mySocket.getOutputStream(), true); 
    
    //Loop through the lines of the confA file, writing them to the socket 
    String line = bufferedReader.readLine(); 
    while (line != null) 
    { 
        //Write the line to the socket, get the next line 
        out.println(line); //updated to println, this flushes and fixes another problem 
        out.flush(); 
        line = bufferedReader.readLine(); 
    } 
    
    //Close the socket 
    mySocket.close(); 
    

    注ノードAのループ作品その:ノードAで

    NodeA nodeA = new NodeA(); 
    NodeB nodeB = new NodeB(); 
    
    new Thread(nodeA).start(); 
    new Thread(nodeB).start(); 
    

    、私はこれを行います良い。私はprintステートメントでテストしたとき、それは永遠にループせず、意図されたテキスト行を通しません。

    その後、ノードBの終わりに:現在のノードBコードin.readyしかし

    //Open the socket 
    ServerSocket mySocket = new ServerSocket(portNum); 
    Socket connectionSocket = mySocket.accept(); 
    
    //Set up a reader on the socket to get what's coming from it 
    BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); 
    
    String line = in.readLine(); //hang occurs here 
    
    while(line != null) { 
        System.out.println(line); 
        line = in.readLine();; 
    } 
    

    に、表示するように更新()は決して真です。 whileループを使用してそれが起こるのを待ってみましたが、決して発生しません。

    私は本当に理由は分かりません。私は正しくソケットをセットアップするかどうか、私が正しく聞いていれば、私は正しくサーバーを設定するか分かりません。

    私はちょうどAを聞いているサーバーにBを作ることが最も理にかなった。それが正しいと思います。それは私がSOのいくつかの他の例を見たものに似ています。

    ありがとうございました。私はソケット、ポート、聞いたりそうでなければ、私はあなたの提案を最初に理解していない場合は私を許して非常に慣れていない。私は私が行くようにそれを理解するために全力を尽くします。

    問題がどこにあるのかわかりやすくするために、コード全体を追加することを控えましたが、もっと情報が必要な場合はお気軽にお問い合わせください。

  • +0

    1) 'ServerSocket.accept()'が返されるたびに、サーバとクライアントの間に接続されたソケットが確立されます。接続に関しては、 'ServerSocket.accept()'をもう一度呼び出さない*。 2)クライアントでは、PrintWriterはデータを内部的にバッファリングします。 'out.print(line);を呼び出した結果をネットワーク上ですぐに見たい場合は、次の文として' out.flush() 'を呼び出さなければなりません。 –

    +0

    'ready()'は、次の読み取りがすぐに戻るかどうかを返します。 [ドキュメント](https://docs.oracle.com/javase/9​​/docs/api/java/io/Reader.html#ready--)を参照してください。 – VGR

    答えて

    2

    サーバは、まずServerSocketからクライアントにSocketを取得する必要があります。

    connectionSocket = mySocket.accept(); 
    

    クライアントがconnectionSocketを受け入れるまで、サーバースレッドはスリープ状態になります。

    あなたはconnectionSocketから読むことができます。 readyは必要ありません。

    これは割り当てであるため、私はあなたに残ります。典型的なサーバが行うだろうところで


    for (;;) { 
        Socket socket = serverSocket.accept(); 
        ... pass the socket to a thread from a pool of threads 
    } 
    
    +0

    ありがとうございますが、これについてはまだまだ混乱しています。サーバーが待機してクライアントが接続したら、別の.accept()を実行する必要はありません。私は最初の.acceptしか持たないように自分のコードを変更しようとしましたが、まだソケットから読み込むことができないようですが、readLine()で永久にハングアップします。 –

    +1

    読み取るSocketを生成する 'ServerSocket.accept'を1つだけ持つべきです。 –

    +0

    ありがとうございます。 .ready()を取り除いて余分な.accepts()を削除し、ハングが発生している場所を表示するようにコードを更新しました。 –

    1

    私はこの問題は、準備がちょうどあなたが読み取りを呼び出す場合、それはブロックしないことを意味していることだと思います。あなたはgrepcode上の機能を調べる場合は、実行されます、コードを見ることができます:

    http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/io/BufferedReader.java#BufferedReader.ready%28%29

    準備スレッドはちょうどあなたが確認したいときに有用である、ブロックすることはないだろうことを意味し、あなたのスレッドISN」あなたがバッファーを持っているかどうかを実際には教えてくれません。

    あなたがしたいことは、データが消費されるまで、ブロックラインとしてreadlineを実行することです。これによって現在のスレッドがブロックされないようにするには、この読み取り専用の新しいコンシューマスレッドをブロックします。

    また、クローズドソケットまたはフラッシュのいずれかで送信通信を終了していることを確認してください。また、オープン/クローズセッションごとに一度だけソケットを受け入れる必要があります。

    +0

    私は現在のスレッドをブロックして読んでも問題ありません。私は最初に.accept()を1つしか持たず、readLine()から返された行がnullでないことを確認するためにin.ready()を変更するようにコードを変更しようとしました。私はしようとしている最初のreadLine()にまだ掛かっています。 –

    +0

    Readlineは文字列の終わりを要求します。\ n EOLまたはクローズドソケットを探しています。ハングアップすると、それはより多くのデータを待っていることを意味します。書き込みの最後に、確認のためのテストとしてライターのソケットを閉じることができます。 – user1442498

    +0

    ありがとうございます。私はmySocket.close()を置いてテストしました。ノードAのコードの終わりに。まだ運はありません。私はもう一方でそれを閉じる必要がありますか? –

    関連する問題