Wiktor Janecki
Wiktor Janecki

Reputation: 73

Java server socket connection reset

When my SECOND client connect to my server I got this error:

Exception in thread "main" java.net.SocketException: Connection reset
    at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
    at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
    at java.base/java.net.SocketInputStream.read(SocketInputStream.java:200)
    at java.base/java.io.DataInputStream.readLine(DataInputStream.java:518)
    at Main.main(Main.java:24)

I don't know what am I doing wrong.

FIRST client works normal

My code:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class Main {
    public static void main(String[] args) throws IOException {
         ServerSocket serverSocket = new ServerSocket(50505);;
         Socket socket;
         while (true) {
             socket = serverSocket.accept();
             while(socket.isConnected()) {
                 String v;
                 DataInputStream in;
                 InputStream in_sock;
                 in_sock = socket.getInputStream();
                 in = new DataInputStream(in_sock);
                 v = in.readLine();
                 System.out.println(v);
                 OutputStream output = socket.getOutputStream();
                 DataOutputStream out = new DataOutputStream(output);
                 out.writeChars("123\n");
                 out.writeChars("123\n");
                 out.writeChars("123\n");
             }
         }
    }
}

PS: How can I share error on stackoverflow? like code?

Upvotes: 4

Views: 3466

Answers (2)

Mataan P
Mataan P

Reputation: 137

So the big issue, like some other people have said, is that your server can only accept one connection because of the lack of multi-threading.

Right now your server waits for a connection to the port specified

socket = serverSocket.accept();

Then while your socket is still connected you read a line from the socket, print it out to System.out, and then write back to the socket all in a loop. Now this comes into issue because next time a client tries to connect to your serverSocket, it can no longer accept connections because your code is stuck in a loop of reading and writing data from one Socket.

The way to fix this is to introduce multithreading in the way that Milen mentioned above.

Your code should look something like this.

public class Main {
    public static void main(String[] args) throws IOException {
         ServerSocket serverSocket = new ServerSocket(50505);
         while (true) {
             Socket socket = serverSocket.accept();
             SocketHandler h = new SocketHandler(socket);
             h.start();
         }
    }
}

public class SocketHandler extends Thread{

    Socket clientSock;
    public SocketHandler(Socket sock){
        clientSock = sock;
    }

    public void run(){
        while(clientSock.isConnected()) {
            String v;
            DataInputStream in;
            InputStream in_sock;
            in_sock = socket.getInputStream();
            in = new DataInputStream(in_sock);
            v = in.readLine();
            System.out.println(v);
            OutputStream output = socket.getOutputStream();
            DataOutputStream out = new DataOutputStream(output);
            out.writeChars("123\n");
            out.writeChars("123\n");
            out.writeChars("123\n");
        }
    }
}

Now this code has a loop that accepts connections, and spawns a new thread for every connection!

I would recommend looking at a few things. First, if you check the Java Docs for ServerSocket you will see this constructor

ServerSocket(int port, int backlog)
Creates a server socket and binds it to the specified local port number, with the specified backlog.

The backlog is the number of incoming connections the server socket can hold onto and store in some sort of buffer until they can be accepted. This is useful if a client is connecting when your accepting loop is in the middle of creating the socket handler. I would recommend putting it at the max number of clients you're expecting.

Secondly, look up the Thread class in the Javadocs. To extend Thread successfully you need to overwrite run(). This method is the method that the thread will execute with. To spawn the thread, you call ThreadObject.start(). You can think of start() as just calling run().

Upvotes: 5

Milen Dyankov
Milen Dyankov

Reputation: 3052

From the "Writing the Server Side of a Socket" tutorial from Oracle:

... the server can service them simultaneously through the use of threads—one thread per each client connection.

The basic flow of logic in such a server is this:

while (true) {
    accept a connection;
    create a thread to deal with the client;
}

The thread reads from and writes to the client connection as necessary.

In that tutorial you'll also find links to a server (KKMultiServer) and thread (KKMultiServerThread) sample implementations.

Upvotes: 2

Related Questions