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


Автор: #Maestro# 16.7.2009, 16:39
и всё же я не понял!! smile 

каким образом чат всегда ожидает сообщение? я так понимаю, что в конструкторе сервера запущено два потока:
один для отправления сообщений, второй - ожидает получение сообщений.

не получается создать второй поток. то есть как только сервер хочет получить сообщение - приложение виснет до тех пор пока сообщение не предёт.
Код


    public void connect()
    {
        try
        {
        socket = new ServerSocket(8923);
       // while (true)
            {

                Runnable r = new TestServerHandler(socket);
                Thread t = new Thread(r);
                t.start();
            }
        }

    class TestServerHandler implements Runnable        //вложенный класс
    {
                public void run()
        {
            try
            {
            incoming = socket.accept();

            .......

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


как написать чат с работающими двумя потоками??

Автор: Galaran 18.7.2009, 15:04
В твоём коде 1й поток просто стартует 2й и завершается. Т.е все действия в одном потоке. А надо для каждого коннекта создавать свой поток.
Если у тебя,  написано вот так:

Код

incoming = socket.accept();
...
   in = reader.readLine(); // находится в бесконечном цикле
...
socket.close();


то поток блокируется на чтении и, поэтому программа не принимает 2й коннект

Код

ss = new ServerSocket(8889);
Socket s = null;
while (true) {
    s = ss.accept();
    Runnable con = new ClientRunnable(s);
    Thread tr = new Thread(con);
    tr.start();
}

class ClientRunnable implements Runnable {
    Socket s;
    BufferefReader in;
    PrintWriter out;

    ClientRunnable(Socket s) {
        this.s = s;
        in = new BufferedReader(BufferedReader(new InputStreamReader(s.getInputStream()));
        out = new PrintWriter(s.getOutputStream(), true);
    }
    
    public void run() {
        String s = in.readLine();
        System.out.println("incoming messange: " + s);
        out.writeln("echo:" + s);
    }
}


В этом случае главный поток постоянно слушает входящие соединения и создает для каждого такого коннекта свой поток.
Каждый дочерний поток блокируется в ожидании сообщения, но главный поток при этом продолжает слушать входящие коннекты.
    

Автор: #Maestro# 21.7.2009, 10:16
извиняюсь, но по-моему в строке 
in = new BufferedReader(BufferedReader(new InputStreamReader(s.getInputStream()));
после первой скобки нехватает слова "new". да и вообще конструктор ClientRunnable(Socket s)
наверное, должен быть throws Exception

вы проверяли этот код? к сожалению, приложение  всё-таки продолжает виснуть... пока не дождётся сообщения,
 но
   s = ss.accept(); // находится в бесконечном цикле while...

кстати класс, соответствующий "ClientRunnable" у меня вложенный, поэтому строка 
this.s = s; в моём случае оказалась лишней. или я зря делаю "ClientRunnable" вложенным??

Код

public void run()
        {
            try
            {
            incoming = socket.accept();

  String line = in.readLine();
  messages.add(line);

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

Автор: Galaran 27.7.2009, 02:30
Сходу написал, хотел показать главный принцип. Зря поторопился

Исправил и проверил, теперь работает:
Код

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author galaran
 */
public class SimpleEchoServer {
    public SimpleEchoServer() throws Exception {
        ServerSocket ss = new ServerSocket(8889);
        Socket s = null;
        while (true) {
            s = ss.accept();
            Runnable con = new ClientRunnable(s);
            Thread tr = new Thread(con);
            tr.start();
        }

    }

    public static void main(String[] args) throws Exception {
        new SimpleEchoServer();
    }

    class ClientRunnable implements Runnable {
        Socket s;
        BufferedReader in;
        PrintWriter out;

        ClientRunnable(Socket s) throws Exception {
            this.s = s;
            in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            out = new PrintWriter(s.getOutputStream(), true); // true - autoflush
        }

        public void run() {
            while (true) {
                try {
                    String income = in.readLine();
                    System.out.println("incoming messange: " + income);
                    out.println("echo:" + income);
                } catch (IOException ex) {
                    System.out.println("I/O error");
                    break;
                }
            }
        }
    }
}


У меня здесь ClientRunnable тоже вложенный.

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