2012-05-10 3 views
2

正しくフラッシュすることを拒否するjava.net.SocketOutputStreamで不満を感じています!私は明らかに見落とさなければならない。以下の私のGroovyスクリプトでは、Galaxy Nexus Android 4.0.2の携帯電話で動作するシンプルなソケットサーバーに接続しようとしましたが、5秒間のタイムアウトが切れた直後にソケットのクローズ例外が発生します。Groovyソケットをフラッシュできない

SocketClient.groovy

import java.net.* 
socket = new Socket() 
socket.connect(new InetSocketAddress(InetAddress.getByAddress([172,17,57,21] as byte[]), 58789), 5000) 
println "Connected!" 
socket.withStreams { input, output -> 
    println "Processing ${input.class.name} and ${output.class.name} streams..." 
    output.withWriter { 
     it << 'echo testing\n\n'; 
     it.flush(); 
     output.flush() 
     def readerThread = Thread.start { 
      println "Request written, reading response..."; println input.text 
     } 
     println "Waiting 5 secs for read to complete." 
     readerThread.join(5000) 
    } 
    println "Stream closed!" 
} 

私は作家フラッシングと間接的にラッピングへの出力ストリームの直接フラッシュを含むフラッシュのすべての異なる手段を、試してみました。ストリームが閉じられてソケットを閉じる原因となるまで、サーバーにデータは表示されず、ソケットから読み取る試行がクラッシュします。私は間違って何をしていますか?下のAndroidコードもインラインで表示します。これは、ソケットサーバーを起動する簡単なアクティビティです。

私は疑問に思ってMyServer.java

package com.example; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.TextView; 

public class MyServer extends Activity 
{ 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     RawSocketServer rawSocketServer = new RawSocketServer(); 
     String port = rawSocketServer.getLocalPort(); 
     TextView textView = (TextView) this.findViewById(R.id.mainTextView); 
     textView.setText("Server bound to port " + port); 
     rawSocketServer.start(); 
    } 
} 

RawSocketServer.java

package com.example; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 

/** 
* Created by IntelliJ IDEA. 
* User: cliff 
* Date: 5/9/12 
* Time: 4:03 PM 
*/ 
public class RawSocketServer { 

    public static final int PORT = 0; 
    private ServerSocket serverSocket; 

    public RawSocketServer() { 
     this(PORT); 
    } 

    public RawSocketServer(int port) { 
     try { 
      this.serverSocket = new ServerSocket(port); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      throw new RuntimeException("server cannot bind to port " + port); 
     } 
    } 

    public void start() { 
     new Thread(new Runnable() { 
      public void run() { 
       go(); 
      } 
     }).start(); 
    } 

    private void go() { 
     Socket socket = null; 
     while (true) { 
      try { 
       socket = this.serverSocket.accept(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("cannot accept from server socket" + e); 
      } 
      BufferedReader reader = null; 
      try { 
       reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("Could not get input stream from socket. " + e); 
      } 
      PrintWriter writer = null; 
      try { 
       writer = new PrintWriter(socket.getOutputStream()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("Could not get output stream from socket. " + e); 
      } 
      try { 
       for (String line = reader.readLine(); line !=null; line = reader.readLine()) { 
        writer.print(line); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("Error reading/writing from/to socket. " + e); 
      } 
     } 
    } 

    public String getLocalPort() { 
     return "" + serverSocket.getLocalPort(); 
    } 
} 

答えて

1

....あなたはそこに "それ< <は、 'テストエコー'" しています。ライターでそれを使用することは、行末が書かれていないことを意味する。あなたのサーバーはreadLineを使用しているので、行の終わりが必要です。したがって、データは到着する可能性がありますが、readLineは行末を待っているため終了していません。この修正は、たとえば、 "< < 'エコーテスト\ n'"または "< <"エコーテスト '< <' \ n '"とすることです。

Android APIについてはあまりよく分かりませんが、readLineで読み込んだ行には行が含まれていないと思うので、あなたのサーバは "writer.print(line);"で同じ問題を抱えている可能性がありますもう終わる。しかし、それは再び読まれないので、現時点では問題にはならないはずです。

+0

ちょっと黒っぽく、いいキャッチ!それは完全に意味がある、私はいくつかを確認します! – Cliff

+0

私は昨夜これをもう一度試して、Groovyソケットクライアントに新しい行を追加しましたが、私はまだ同じ動作をします。私はちょうどサーバーが同じ問題を抱えているかもしれないというあなたの言及を思いついたので、次にそれを試してみましょう。 – Cliff

1

私はBlackdragの助けを借りてこれを最終的に見つけました。私の問題は複数の分野でした。改行がないためにクライアントの読み込みが停止する(blackdragが示唆しているように)。また、クライアントが書き込みストリームを閉じないため、サーバーの読み取りループがハングします。これは、書き込みストリームを閉じると読み取りストリームを閉じるソケットを閉じる、チキンと卵の問題につながります。私は会話がいつ終了し、サーバーが読み込みを停止してソケットを閉じるべきかを示す「プロトコル」を入れる必要がありました。クライアントに「完了」文字列を書き込むことはその指標になります。 (これはひどいAndroidコードですが、当初は新しいGalaxy Nexusでの通信をテストするためのものでしたが、これはまだiOSの使用方法を学んでいます)

SocketClient.groovy

import java.net.* 
socket = new Socket() 
socket.connect(new InetSocketAddress(InetAddress.getByAddress([172,17,57,21] as byte[]), 58302), 5000) 
println "Connected!" 
socket.withStreams { input, output -> 
    println "Processing ${input.class.name} and ${output.class.name} streams..." 
    output.withWriter { 
     it << 'my name is cliff\ndone\n'; 
     it.flush(); 
     output.flush() 
     def readerThread = Thread.start { 
      println "Request written, reading response..."; println input.text 
     } 
     println "Waiting 5 secs for read to complete." 
     readerThread.join(60000) 
    } 
    println "Stream closed!" 
} 

MyServer.java

package com.example; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.TextView; 

public class MyServer extends Activity 
{ 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     RawSocketServer rawSocketServer = new RawSocketServer(); 
     String port = rawSocketServer.getLocalPort(); 
     TextView textView = (TextView) this.findViewById(R.id.mainTextView); 
     textView.setText("Server bound to port " + port); 
     rawSocketServer.start(); 
    } 
} 

RawSocketServer.java

package com.example; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 

/** 
* Created by IntelliJ IDEA. 
* User: cliff 
* Date: 5/9/12 
* Time: 4:03 PM 
*/ 
public class RawSocketServer { 

    public static final int PORT = 0; 
    private ServerSocket serverSocket; 

    public RawSocketServer() { 
     this(PORT); 
    } 

    public RawSocketServer(int port) { 
     try { 
      this.serverSocket = new ServerSocket(port); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      throw new RuntimeException("server cannot bind to port " + port); 
     } 
    } 

    public void start() { 
     new Thread(new Runnable() { 
      public void run() { 
       go(); 
      } 
     }).start(); 
    } 

    private void go() { 
     Socket socket = null; 
     while (true) { 
      try { 
       socket = this.serverSocket.accept(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("cannot accept from server socket" + e); 
      } 
      BufferedReader reader = null; 
      try { 
       reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("Could not get input stream from socket. " + e); 
      } 
      PrintWriter writer = null; 
      try { 
       writer = new PrintWriter(socket.getOutputStream()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("Could not get output stream from socket. " + e); 
      } 
      try { 
       for (String line = reader.readLine(); line !=null; line = reader.readLine()) { 
        if(line.trim().equalsIgnoreCase("done")) break; 
        writer.println(line); 
        writer.flush(); 
       } 
       writer.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException("Error reading/writing from/to socket. " + e); 
      } 
     } 
    } 

    public String getLocalPort() { 
     return "" + serverSocket.getLocalPort(); 
    } 
} 
+0

あなたの問題を解決してくれて嬉しいです – blackdrag

+0

助けを頼りに! – Cliff

関連する問題