I am trying to adapt my simple socket server so that it can have multiple TCP connections, via multithreading, but I can't seem to get it to work. My code so far is as follows, I'm not really sure where to go from here :
import java.net.*; import java.io.*; public class DoSomethingWithInput implements Runnable { private final Socket clientSocket; //initialize in const'r public void run() { BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String nextline; while ((nextline = in.readLine())!=null) { System.out.println(nextline); } //... close socket, etc. } } public class Socket{ public Socket() { } @Override public void run() { try { ServerSocket serverSocket = null; serverSocket = new ServerSocket(5432); for (;;) { ServerSocket serverSocket = null; serverSocket = new ServerSocket(5432); for (;;) { Socket clientSocket = null; clientSocket = serverSocket.accept(); //delegate to new thread new Thread(new DoSomethingWithInput(clientSocket)).start(); } } }catch (IOException e) { System.err.println("Could not listen on port: 5432."); System.exit(1); } } }
Would anyone be able to give me some pointers on how I could do this, and why my current implementation will not work ? I was running through the tips in the Java tutorial http://download.oracle.com/javase/tutorial/networking/sockets/examples/KKMultiServerThread.java here, but the example they give here seems to use a lot of outside sources and classes like KnockKnockProtocol etc etc.
Would anyone be able to help me out with this?
Thank you very much!
To create a server application that can handle multiple connections, a new execution thread needs to be created for each connection. The following program, called ReverseEchoServer, offers the same function to client program. But it can handle multiple connections.
@asma, yes. Both clients can run on the same machine.
The problem is that currently you're accepting the connection, but then immediately performing blocking reads on it until it's closed:
// After a few changes... Socket clientSocket = serverSocket.accept(); BufferedReader in = new BufferedReader(new InputStreamReader( clientSocket.getInputStream())); String nextLine; while ((nextLine = in.readLine()) != null) { System.out.println(nextline); }
That means the same thread which accepts the connection is trying to handle the connection. That won't let you use multiple connections at the same time.
Instead, create a class (e.g. ConnectionHandler
) which implements Runnable
, and has a constructor taking a Socket
. Its run
method should handle the connection. Then change your code to:
Socket clientSocket = serverSocket.accept(); Runnable connectionHandler = new ConnectionHandler(clientSocket); new Thread(connectionHandler).start();
That will leave your "main" thread free to wait for the next connection.
(By the way, the KnockKnockProtocol
class isn't really "external" - it's part of the example. They just didn't make it very clear that the source is here...)
You're not multithreading. You're creating a thread which binds on a port and then reads from any client socket until the connection is closed.
You need to pass the socket to a new thread and have it read.
public class DoSomethingWithInput implements Runnable { private final Socket clientSocket; //initialize in const'r public void run() { BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String nextline; while ((nextline = in.readLine())!=null) { System.out.println(nextline); } //... close socket, etc. } } //... ServerSocket serverSocket = null; serverSocket = new ServerSocket(5432); for (;;) { Socket clientSocket = null; clientSocket = serverSocket.accept(); //delegate to new thread new Thread(new DoSomethingWithInput(clientSocket)).start(); } //...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With