Создание сервера сокетов, который позволяет несколько подключений через потоки и Java
Я пытаюсь адаптировать мой простой сервер сокетов, чтобы он мог иметь несколько TCP-соединений через многопоточность, но я не могу заставить его работать. Мой код до сих пор следующий, я не совсем уверен, куда идти отсюда:
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);
}
}
}
Кто-нибудь сможет дать мне несколько указателей на то, как я могу это сделать, и почему моя текущая реализация не будет работать? Здесь я читал подсказки в учебнике Java http://download.oracle.com/javase/tutorial/networking/sockets/examples/KKMultiServerThread.java, но пример, который они здесь приводят, похоже, использует множество внешних источников и классов как KnockKnockProtocol и т.д. и т.д.
Кто-нибудь сможет мне помочь?
Большое спасибо!
Ответы
Ответ 1
Проблема заключается в том, что в настоящее время вы принимаете соединение, но затем сразу же выполняете блокировку чтения до его закрытия:
// 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);
}
Это означает, что тот же поток, который принимает соединение, пытается обработать соединение. Это не позволит вам одновременно использовать несколько подключений.
Вместо этого создайте класс (например, ConnectionHandler
), который реализует Runnable
, и имеет конструктор с Socket
. Его метод run
должен обрабатывать соединение. Затем измените свой код на:
Socket clientSocket = serverSocket.accept();
Runnable connectionHandler = new ConnectionHandler(clientSocket);
new Thread(connectionHandler).start();
Это приведет к тому, что ваш "основной" поток будет ждать следующего соединения.
(Кстати, класс KnockKnockProtocol
на самом деле не является "внешним" - это часть примера. Они просто не дали понять, что здесь...)
Ответ 2
Ты не многопоточность. Вы создаете поток, который привязывается к порту, а затем читает с любого клиентского сокета, пока соединение не будет закрыто.
Вам нужно передать сокет в новый поток и прочитать его.
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();
} //...