сервер не получает данные от нескольких клиентов (сокеты Java) - PullRequest
0 голосов
/ 08 января 2012

Я написал простую программу, в которой сервер должен печатать данные, отправленные несколькими клиентами.Но сервер получает только частичные данные.Ниже приведены соответствующие части кода.

Сервер:

try {
        serverSocket = new ServerSocket(8888);
    } catch (IOException e) {
        System.err.println("Could not listen on port: 8888");
        System.exit(-1);
    }
 while (listening) {
    Socket clientSocket = serverSocket.accept();
    BufferedReader reader = new BufferedReader(new InputStreamReader(
                            clientSocket.getInputStream()));
        System.out.println(reader.readLine());

        reader.close();
        clientSocket.close();
  }
  serverSocket.close();

Клиент:

  try {
        socket = new Socket("nimbus", 8888);
        writer = new PrintWriter(socket.getOutputStream(), true);
        localHost = InetAddress.getLocalHost();
    } 
    catch (UnknownHostException e) {} 
    catch (IOException e) {}

    StringBuilder msg1 = new StringBuilder("A: ");
    for(int i=1; i<=3; i++)
        msg1.append(i).append(' ');
    writer.println(localHost.getHostName() + " - " + msg1);

    StringBuilder msg2 = new StringBuilder("B: ");
    for(int i=4; i<=6; i++)
        msg2.append(i).append(' ');
    writer.println(localHost.getHostName() + " - " + msg2);

    StringBuilder msg3 = new StringBuilder("C: ");
    for(int i=7; i<=9; i++)
        msg3.append(i).append(' ');
    writer.println(localHost.getHostName() + " - " + msg3);

    writer.close();
    socket.close();

Я получаю следующий вывод (при запуске на 3 клиентах)

nimbus2 - A: 1 2 3 
nimbus3 - A: 1 2 3 
nimbus4 - A: 1 2 3

Я не получаю второе и третье сообщения.Сервер продолжает ждать.Куда я иду не так?

Редактировать: В коде сервера я попытался удалить reader.close() и clientSocket.close().Это тоже не сработало.Другой вопрос - если 3 клиента отправляют 3 сообщения, требуется ли 9 подключений?(по этой причине я закрыл соединение в коде сервера)

Ответы [ 3 ]

1 голос
/ 08 января 2012

Вы, вероятно, хотите делегировать передачу сокета другому потоку.Я написал пример, который работает, передавая каждый входящий сокет Исполнителю, чтобы он мог прочитать все входные данные.Я использую Executors.newCachedThreadPool (), который должен вырасти до необходимого размера.Вы также можете использовать Executors.newFixedThreadPool (1), если хотите, чтобы он мог обрабатывать только 1 клиента за раз.

Единственное другое изменение, которое я сделал, я удалил BufferedReader и заменил его сканером.У меня были проблемы с BufferedReader, не возвращающим данные.Я не уверен почему.

Executor exe = Executors.newCachedThreadPool();
ServerSocket serverSocket = null;
try {
    serverSocket = new ServerSocket(8888);
} catch (IOException e) {
    System.err.println("Could not listen on port: 8888");
    System.exit(-1);
}
while (listening) {
    final Socket clientSocket = serverSocket.accept();

    exe.execute(new Runnable() {

        @Override
        public void run() {
            try {
                Scanner reader = new Scanner(clientSocket.getInputStream());
                while(reader.hasNextLine()){
                    String line = reader.nextLine();
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

}
serverSocket.close();
0 голосов
/ 08 января 2012

Джон прав.Вы закрываете клиентское соединение, вызывая clientsocket.close () после прочтения сообщения, поэтому вы не можете получить другие сообщения.Вы должны вызывать clientsocket.close (), когда вы получили все сообщения

0 голосов
/ 08 января 2012

Похоже, вы закрываете соединение с клиентом до того, как он может закончить запись / до того, как сервер прочитает все отправленные им сообщения.Я думаю, вам нужно продолжить readline и, возможно, не прерывать соединение клиента после того, как они отправят вам одно сообщение.

...