【问题标题】:How to continue read InputStream in loop used Socket-connection?如何在循环使用的套接字连接中继续读取 InputStream?
【发布时间】:2017-03-10 20:28:20
【问题描述】:

在Server站点中,我使用循环继续读取从客户端发送的数据,但是当我从客户端发送数据时,服务器站点抛出异常。

我调试了服务器站点可以从客户端读取数据的代码,但是当它从客户端读取数据时,循环无法停止,我猜这个异常是由这个引起的!

如何解决这个问题,当MAX_INPUT小于发送到服务器的数据时,服务器可以继续正确读取!

正如答案所说,我在 finally 块的客户端站点中添加了socket.close(),它修复了连接重置问题。

同时,我设置了Server站点MAX_INPUT = 8,使Server可以继续读取输入字节并将其发送回客户端。但是结果是客户端收不到完整的数据:

Server's response is: This is 
Server's response is: This is 
Server's response is: This is Seq.0 request send to server!
Server's response is: This is Seq.3 request send to server!
Server's response is: This is Seq.4 request send to server!

或者有时服务器站点会抛出异常,例如:

java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at com.simple.server.Server$Handler.run(Server.java:44)
at java.lang.Thread.run(Unknown Source)

服务器站点代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class Server implements Runnable {
    public final static int port = 8080;
    public final static String host = "127.0.0.1";
    public final static int MAX_INPUT = 1024;

    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("Server begin to listen to port to accept!\n");
            while (!Thread.interrupted()) {
                Socket socket = serverSocket.accept();
                new Thread(new Handler(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static class Handler implements Runnable {

        private Socket _socket;

        Handler(Socket socket) {
            _socket = socket;
        } 

        public void run() {
            try {

                InputStream in = _socket.getInputStream();
                OutputStream out = _socket.getOutputStream();

                int read;
                byte[] buf = new byte[MAX_INPUT];
                // I use a loop to continue to read 
                // data from client
                while ((read = in.read(buf)) != -1)
                    out.write(buf, 0, read);

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    _socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
     }

    public static void main(String args[]) {
        new Thread(new Server()).start();
    }

}

客户站点代码:

public class Client implements Runnable {

    public final static String host = "127.0.0.1";
    public final static int port = 8080;
    public final static int MAX_INPUT = 1024;

    private int seq;

    Client(int seq) {
        this.seq = seq;
    }

    public void run() {
        try {

            Socket client = new Socket(host, port);


            OutputStreamWriter writer = new  OutputStreamWriter(client.getOutputStream());
            InputStreamReader reader = new InputStreamReader(client.getInputStream());
            writer.write("This is Seq." + seq + " request send to server!");
            writer.flush();

            char[] buf = new char[MAX_INPUT];
            int len = reader.read(buf);
            String response = new String(buf, 0, len);

             System.out.println("Server's response is: " + response);
         } catch (IOException e) {
             e.printStackTrace();
         }
    }

    public static void main(String args[]) {

        Thread threads[] = {
            new Thread(new Client(0)), 
            new Thread(new Client(1)), 
            new Thread(new Client(2)),
            new Thread(new Client(3)), 
            new Thread(new Client(4))
         };

        for(Thread thread : threads)
            thread.start();
     }
 }

抛出异常:

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at com.simple.server.Server$Handler.run(Server.java:44)
at java.lang.Thread.run(Unknown Source)

【问题讨论】:

  • 你如何在服务器端访问 MAX_INPUT 而不初始化它!!??
  • 我用public final static int MAX_INPUT = 1024;初始化它
  • 抱歉看到了
  • 您收到连接重置异常,主要是因为您的客户端会丢失连接(因为网络问题)
  • 如果不使用循环,改成byte[] buf = new byte[MAX_INPUT];int read = in.read(buf);System.out.println(new String(buf, 0, read));out.write("Hello World".getBytes());就可以正常运行了!

标签: java sockets io


【解决方案1】:

您的服务器正在读取输入,直到流结束并在传输过程中回显它。您的客户端正在发送一个请求并读取一个响应并且从不关闭套接字。因此,不是服务器遇到流结束,而是在客户端进程退出时遇到连接重置。

解决方法:在客户端关闭socket。

【讨论】:

  • 我关闭了客户端中正确运行的socket!
猜你喜欢
  • 2018-05-14
  • 2012-05-22
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
  • 2013-04-19
  • 2015-08-29
  • 2012-10-07
  • 1970-01-01
相关资源
最近更新 更多