Creating a socket server which allows multiple con

2019-01-08 12:17发布

问题:

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!

回答1:

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...)



回答2:

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


标签: java sockets