2016-10-22 7 views
1

私はクライアントとサーバーを持っています。クライアントは単に1行の入力をサーバーに送信し、応答を出力します。SocketException recvが失敗しましたが、なぜですか?

私は

SocketException (Software caused connection abort: recv failed) 
    [...] 
    at java.io.InputStreamReader.read(InputStreamReader.java:168) 
    at hw3.Client.readLine(Client.java:37) 
    at hw3.Client.main(Client.java:28) 

デバッガは、ソケットは、読み取り時には閉じていないことを私に伝え取得しています、他に何この例外を引き起こす可能性がありますか?

私はスレッディングのために問題に遭遇していると思いますが、何かが「間違っている」と言い張っていますか?

public class Client 
{ 
    public static final int PORT = ReversingEchoServerDispatcher.PORT; 
    private static final String host = "localhost"; 
    private static Socket sock; 

    public static void main(String[] args) 
     throws IOException 
    { 
     try(Socket sock = new Socket(host, PORT); 
      InputStreamReader clin = new InputStreamReader(sock.getInputStream()); 
      OutputStream clout = sock.getOutputStream(); 
      Scanner sc = new Scanner(System.in)) 
     { 
      Client.sock = sock; 

      byte[] cl = sc.nextLine().getBytes("UTF-8"); 
      clout.write(cl); 
      System.out.println(readLine(clin)); 
     } 
    } 

    private static String readLine(InputStreamReader in) 
     throws IOException 
    { 
     StringBuilder sb = new StringBuilder(); 
     for(int i = in.read(); i != -1; i = in.read()) 
     { 
      char c = (char) i; 
      if(c != '\n') sb.append(c); 
      else break; 
     } 
     return sb.toString(); 
    } 
} 

public class ServerDispatcher 
{ 
    public static final int PORT = 8034; 
    public static void main(String[] args) 
    { 
     try (ServerSocket serversock = new ServerSocket(PORT)) 
     { 
      while(true) 
      { 
       Socket socket = serversock.accept(); 
       ServerLogic sv = new ServerLogic(socket); 
       new Thread(() -> { 
        try { 
         sv.run(); 
        } catch (IOException ex) { 
         ex.printStackTrace(System.err); 
        } 
       }).start(); 
      } 
     } 
     catch(IOException e) 
     { 
      e.printStackTrace(System.err); 
     } 
    } 
} 

記録のために、ServerLogicクラスは次のようになります。私の終了コードは1、ない-999であるので、(そのsocket.closeではありません)

class ServerLogic 
{ 
    Socket socket; 

    public 
    ServerLogic(Socket s) 
    { 
     this.socket = s; 
    } 

    public void run() 
     throws IOException 
    { 
     try(InputStreamReader in = new InputStreamReader(socket.getInputStream()); 
      OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream())) 
     { 
      StringBuilder sb = new StringBuilder(); 
      while(in.ready()) { 
       char c = (char) in.read(); 
       if(c == '\n') { 
        String str = process(sb); 
        if(str != null) out.write(str); 
        else return; 
       } else { 
        sb.append(in.read()); 
       } 
      } 
     } finally { 
      try { 
       socket.close(); 
      } catch(IOException ex) { 
       ex.printStackTrace(System.err); 
       System.exit(-999); 
      } 
     } 
    } 

    private static String process(StringBuilder sb) 
    { /* ... */ } 
+0

書き込み後にクライアント側のcloutで 'flush()'を呼び出してみてください。 – MeBigFatGuy

+0

いいえ、それはそれを修正しませんでした。 –

+0

私はin.ready()も使用しません。ポイントはありません。すぐにnullを返すとどうなりますか?何も起こりません...それを取り除いてください...ただ読んでください – MeBigFatGuy

答えて

0

を失敗しているサーバーは、入力を終了するために改行\nを期待していますが、クライアントからの1を送信することはありません。 sc.nextLine()は入力行を返しますが、終端改行は含みません。 while(in.ready())ループが最終的に終了し、サーバーは応答を送信せずにソケットを閉じます。

+0

sc.nextLine()に改行を手動で追加しても、それが修正されませんでした( 'byte [] cl =(sc.nextLine()+ '\ n')。 getBytes( "UTF-8"); ')、私はあなたの答えを正しく理解しましたか? –

+0

また、 'clout'を' PrintWriter'に変更し、 'clout.println(sc.nextLine())'を使ってみましたが、これもうまくいきませんでした。 –

関連する問題