Консультация № 173897
01.11.2009, 19:06
35.00 руб.
0 1 1
Здраствуйте Уважаемые эксперты,
Мне нужно написать на яве многоклиентный чат, один сервер и несколько клиентов,
Подскажите пожалуйста как это можно реализовать? Если клиент один, то всё просто, а если много, как узнать когда от кого приходят данные на сервер? На c++ использовал функцию select() и потом FD_ISSET, как можно подобное зделать на яве?
В приложении каркас одноклиентного сервера.

Приложение:
import java.net.*;
import java.io.*;

public class EchoServer{
public static void main(String args[]){
int port = -1;

if (args.length != 1){
System.err.println("USAGE: java EchoServer <port>");
return;
}

try {
port = Integer.parseInt(args[0]);
}
catch(NumberFormatException e){
System.err.println("Error #1: bad port number");
return;
}

try {
ServerSocket serverSocket = new ServerSocket(port);
while(true){
Socket clientSocket = serverSocket.accept();

System.out.println("Client connected: "+clientSocket.
getInetAddress().getHostAddress());
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));

String buffer = null;
while((buffer = in.readLine()) != null){
out.println(buffer);
}
System.out.println("Client disconnected: "+clientSocket.
getInetAddress().getHostAddress());
in.close();
out.close();
clientSocket.close();

}
}
catch (Exception e){
System.err.println("Error #9999: Unexpected exception: "+
e.getMessage());
}
}
}

Обсуждение

Неизвестный
01.11.2009, 22:02
общий
это ответ
Здравствуйте, Станислав.
Точно также узнавать. Данные-то приходят через определенный сокет.
Я бы сделал так: класс ClientConnection. Каждый его экземпляр крутится в своем потоке.
В нем поля с параметрами соединения.
Метод ServeClient:
1 ждет соединения.
2 запускает новый экземпляр класса в новом потоке
3 выполняет идентификацию пользователя (логин/пароль)
4 Регистрирует себя в списке соединений
5 В цикле ждет строки от пользователя
6 Каждую строку передает методу EchoMessage.
7 После разрыва соединения убирает себя из списка соединений и завершает свой поток.

Статическое поле - коллекция ActiveConnections - список всех работающих соединений.

Статический синхронизованный метод EchoMessage:
В цикле проходит по всем соединениям и пересылает каждому строку-параметр.

При запуске сервера создаем первый объект соединения и запускаем его метод ServeClient в новом потоке. Он сам следующий запустит при новом соединении. Потом он просто ждет сообщения от пользователя и передает их методу EchoMessage, а тот уже их рассылает каждому. Можно это все сделать и в одном потоке с асинхронными вызовами, но это будет гораздо сложней выглядеть.
Клиента написать попроще. Но там тоже 2 потока: один ожидает ввод пользователя, другой - сообщение от севера.
Если где-то застрянете - обращайтесь. Но на Яве я такой код писать не буду, я уже не очень хорошо язык помню. На С#, возможно, написал бы.
Форма ответа