Создание сервера сокетов, который позволяет несколько соединений через потоки и Java - PullRequest
31 голосов
/ 24 февраля 2011

Я пытаюсь адаптировать мой простой сервер сокетов, чтобы он мог иметь несколько 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 и т. Д. И т. Д.

Кто-нибудь сможет мне помочь с этим?

Большое спасибо!

Ответы [ 2 ]

52 голосов
/ 24 февраля 2011

Проблема в том, что в данный момент вы принимаете соединение, но затем сразу же выполняете блокировку чтения на нем, пока оно не закроется:

// 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 недействительно "внешний" - это часть примера. Они просто не очень ясно дали понять, что источник здесь ...)

19 голосов
/ 24 февраля 2011

Вы не многопоточны. Вы создаете поток, который связывается с портом и затем читает из любого клиентского сокета, пока соединение не будет закрыто.

Вам нужно передать сокет в новый поток и прочитать его.

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();
} //...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...