Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Клиент-Сервер конект


Автор: TwisT_X 7.1.2010, 19:34
Добрый вечер... 
Писал сервер для игры в шахматы (задание курсовой работы) и столкнулся с непонятной для меня проблемой:

Код

        ServerSocket cs = null;
        Socket player1 = null, player2 = null;
        OutputStream os;
        try {
            cs = new ServerSocket(1988);
        } catch (IOException e) {
            System.out.println("Couldn't listen to port 1988");
            System.exit(-1);
        }
        System.out.println("Waiting for players ...");
        try {
            player1 = cs.accept();
            os = player1.getOutputStream();
            System.out.println("Player #1 connected: " + player1);
            os.write("Wellcome to server of chess. You are the first player.".getBytes());
            player2 = cs.accept();
            System.out.println("Player #2 connected: " + player2);
            os = player2.getOutputStream();
            os.write("Wellcome to server of chess. You are the second player.".getBytes());
        } catch (IOException e) {
            System.out.println("Can't accept");
            System.exit(-1);
        }


По коду понятно что я хочу, когда подключается клиент к серверу, чтобы сервак написал клиенту, что подконектился.. Но получается при реализации: сервак запускается и ждет клиентов... Заходит первый и сервак ничего не отправляет... Потом заходит второй и сервак отправляет сразу обоим сообщения... Как сделать чтобы отправляло сразу первому не дожидаясь второго? 

P.S. если убрать блок try то результат не изменится..

Автор: jk1 7.1.2010, 20:00
1) Потоки (Streams) надо закрывать методом close(); после использования. Если поток буферизованный, будет полезно также вызвать flush(); для слива содержимого буфера вызовом native API. 

2) Взаимодействие сервера с несколькими клиентами, как правило, реализуется созданием отдельного потока для работы с каждым из клиентов, например:
Код

public class KKMultiServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;

        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(-1);
        }

        while (listening)
        new KKMultiServerThread(serverSocket.accept()).start();

        serverSocket.close();
    }
}

Код

public class KKMultiServerThread extends Thread {
    private Socket socket = null;

    public KKMultiServerThread(Socket socket) {
    super("KKMultiServerThread");
    this.socket = socket;
    }

    public void run() {

    try {
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                    socket.getInputStream()));

        // здесь обрабатываете input, результат пишете в output
        out.close();
        in.close();
        socket.close();

    } catch (IOException e) {
        e.printStackTrace();
    }
    }
}

Автор: TwisT_X 7.1.2010, 20:23
Получается мне надо использовать потоки Thread. Главным будет сам сервак и два дочерних - клиенты.. Я правильно понял?

Автор: jk1 7.1.2010, 20:39
Нет. Это все серверные потоки: один основной + по одному для обслуживания каждого клиента

Автор: TwisT_X 7.1.2010, 20:52
ой так сразу тяжело все впитать... Получается сервер выделяет два дочерних потока для двух сокетов и работает с ними по отдельности?

Я сейчас буду пробовать... Можно с тобой как-то связаться по ICQ или еще как-то для дальнейшего совета?

Автор: jk1 7.1.2010, 21:31
На форуме есть PM. Пиши, если будут еще вопросы по теме.

Автор: alon4ik 12.1.2010, 00:14
Цитата(TwisT_X @ 7.1.2010,  20:52)
ой так сразу тяжело все впитать... Получается сервер выделяет два дочерних потока для двух сокетов и работает с ними по отдельности?

jk1 достаточно хорошо разъяснил.
Вам необходимо, чтобы в главном потоке сервера создавался сервер-сокет. Если подконнектился клиент - вы в отдельном потоке обрабатываете его запрос и отсылаете ответ (работаете на уровне инпут- и аутпутстримов).
Примеры реализации клиент-серверного взаимодействия посмотрите здесь: http://java2s.com/Code/Java/Network-Protocol/ThreadedServerwithServerSocket.htm, http://java2s.com/Code/Java/Network-Protocol/Createasocketwithatimeout.htm



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)