简体   繁体   中英

How to continue read InputStream in loop used Socket-connection?

In Server site, I use a loop to continue to read data sent from the client, but when I send data through from the client, the server site throw exception.

I debug the code that the server site can read the data from client, but when it finish read from the client, the loop can't stop, I guess the exception was cause by that!

How can I fixed such this problem, when the MAX_INPUT was smaller than the data send to the server, the Server can continue read it correctly!

As the answer say, I add the socket.close() in the client site in finally block, it fixed the Connection reset problem.

At the same time, I set the Server site MAX_INPUT = 8 , that Server can continue to read the input bytes and send it back to the client. But the result is that the client can't receive the complete data:

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!

Or sometimes server site throw exception like:

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)

The Server site code:

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();
    }

}

The client site code:

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();
     }
 }

The throw Exception:

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)

Your server is reading the input until end of stream and echoing it as it goes. Your client is sending one request and reading one response and never closing the socket. So instead of the server encountering end of stream, it is encountering a connection reset when the client process exits.

Solution: close the socket in the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM