Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Заставить несколько клиентов увидеть друг друга 
V
    Опции темы
webrider
Дата 24.12.2010, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Здравствуйте, мне снова нужна ваша помощь...
Нужно увидеть всех клиентов в сети и построить их список, чтобы потом можно было подключиться к выбранному посредством отправки запроса и его подтверждению на противоположном сокете.
Всё это должно быть одном приложении, т.е. клиенты равнозначны, они должны увидеть друг друга.
Итак, как я понял, для этого нужно использовать многопоточность. Как я это вижу:
1) Приложение пытается подключиться (пока на локалхосте) к порту 2012.
2) Если не получается, то создаётся сервер, который слушает подключения.
3) Если получается, то вынести подключение в отдельный поток (с одной стороны создаётся клиентский поток, с другой - серверный).
Но я не совсем улавливаю логику, вот мои коды:
Потоки практически одинаковые, можно смотреть один)
Код

public class serverThread extends Thread
{
    private Socket socket;
    private BufferedReader br;
    private PrintWriter pw;
    
    public serverThread (Socket s) throws IOException
    {
        System.out.println("Create Server thread");
        socket = s;
        br =
          new BufferedReader(
            new InputStreamReader(
              socket.getInputStream()));
        // Включаем автоматическое выталкивание:
        pw =
          new PrintWriter(
            new BufferedWriter(
              new OutputStreamWriter(
                socket.getOutputStream())), true);
        // Если любой из вышеприведенных вызовов приведет к
        // возникновению исключения, то вызывающий отвечает за
        // закрытие сокета. В противном случае, нить
        // закроет его.
        start(); // вызываем run()
    }
    
    public void run()
    {
        try 
        {
            pw.println(socket);
            while (true) 
            { 
                String str = br.readLine();
                if (str.equals("END")) 
                    break;
                System.out.println("Echoing: " + str);
            }
            System.out.println("closing...");
        } 
        catch(IOException e) 
        {
            System.err.println("IO Exception");
        } 
        finally 
        {
            try 
            {
                socket.close();
            } 
            catch(IOException e) 
            {
                System.err.println("Socket not closed");
            }
        }
    }
}

Код

public class clientThread extends Thread
{
    private Socket socket;
    private BufferedReader br;
    private PrintWriter pw;

    public clientThread (Socket s) throws IOException
    {
        socket = s;
        br =
          new BufferedReader(
            new InputStreamReader(
              socket.getInputStream()));
        // Включаем автоматическое выталкивание:
        pw =
          new PrintWriter(
            new BufferedWriter(
              new OutputStreamWriter(
                socket.getOutputStream())), true);
        // Если любой из вышеприведенных вызовов приведет к
        // возникновению исключения, то вызывающий отвечает за
        // закрытие сокета. В противном случае, нить
        // закроет его.
        start(); // вызываем run()
    }

    public void run()
    {
        try
        {
            pw.println(socket);
            while (true)
            {
                 String str = br.readLine();
                if (str.equals("END"))
                    break;
                System.out.println("Echoing: " + str);
            }
            System.out.println("closing...");
        }
        catch(IOException e)
        {
            System.err.println("IO Exception");
        }
        finally
        {
            try
            {
                socket.close();
            }
            catch(IOException e)
            {
                System.err.println("Socket not closed");
            }
        }
    }
}

Код

public void getClientList() throws IOException, InterruptedException
{
    Socket clientSocket = null;
    ServerSocket serverSocket = null;
    int portPrev = 0;
    while (true)
    {
        try
        {
             clientSocket = new Socket("localhost", 2012);
             int port = clientSocket.getLocalPort();
             if (portPrev != port)     //тут я хотел сделать проверку, чтобы не произошло зацикливания...
             try
             {
                 new clientThread(clientSocket);
                 portPrev = port;
             }
             catch(IOException e)
             {
                 // Если завершится неудачей, закрывается сокет,
                 // в противном случае, нить закроет его:
                 clientSocket.close();
             }
             isClient = 0;
        }
        catch(Exception e)
        {
            System.out.println("No clients! Create server!");
        }
        
         try
         {
             serverSocket = new ServerSocket(2012);
         }
         catch (IOException e)
         {
             System.out.println(e);
             System.exit(-1);
         }

            try
            {
                System.out.println("Waiting for a client...");
                clientSocket = serverSocket.accept();
                try
                {
                    new serverThread(clientSocket);
                }
                catch(IOException e)
                {
                    // Если завершится неудачей, закрывается сокет,
                    // в противном случае, нить закроет его:
                    clientSocket.close();
                }
                System.out.println("Client connected");
            }
            catch (Exception e)
            {
                System.out.println("Can't accept");
                System.exit(-1);
            }
    }
}


Прошу помощи, хотя бы советом, как это должно быть...
По-идее, в консоли должен построиться список вида:
Echoing: Socket[addr=localhost/127.0.0.1,port=2012,localport=64749]
Echoing: Socket[addr=localhost/127.0.0.1,port=2012,localport=64750]
...
А у мну ошибка
Код

java.net.BindException: Address already in use: JVM_Bind
Echoing: Socket[addr=localhost/127.0.0.1,port=2012,localport=65170]
Java Result: -1


Это сообщение отредактировал(а) webrider - 24.12.2010, 20:14
PM MAIL   Вверх
COVD
Дата 25.12.2010, 03:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 11
Всего: 43



PM MAIL   Вверх
webrider
Дата 25.12.2010, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



COVD, спасибо за ссылку, но это нужно реализовать на сокетах...
Беда ещё в том, что это трудно проверить на локалхосте, а в локалке проверить не могу (роутер сдох:()
Как я понимаю, каждое новое приложение, после коннекта со всеми предыдущими должно создать сервер сокет для того, чтобы к нему могли подключиться последующие.
Т.е. у первого приложения только серверные сокеты, у второго - 1 клиентский с первым, остальные серверные... у последнего все клиентские, 1 серверный...
Но при попытке создания второго приложения, возникает ожидаемая ошибка, т.к. они дерутся за 1 порт (на локалхосте, я имею ввиду)...
Поправьте, пожалуйста, где я не прав и скажите, можно ли всю эту схему осуществить на одном компе?
PM MAIL   Вверх
COVD
Дата 25.12.2010, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 11
Всего: 43



Еще более простой пример Hazelcast. Это пример распределенной памяти, т.е. еще более высокий уровень абстракции и скорее всего это и есть конечная цель ваших усилий.

Если же хотите делать сами с нуля, то для поиска компьютеров в сети используют сокеты UDP, мультикастинг. Сначала запускается серверный сокет на любом свободном порту. Делается так - если порт занят и получено java.net.BindException, то номер порта увеличивается на 1 и попытка повторяется. Потом приложение рассылает по всем адресам сети номер порта своего серверного сокета. Другие, ранее запущенные приложения, в ответе сообщают свои серверные порты. Поскольку для открытия серверного сокета используется любой свободный порт, то все приложения группы могут быть запущены на одном компьютере. У всех будет один адрес, но разные номера серверных портов.

Все же рекомендую посмотреть JGroup. Это opensource, там код доступен.

Это сообщение отредактировал(а) COVD - 25.12.2010, 18:26
PM MAIL   Вверх
webrider
Дата 28.12.2010, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Проблемы решил.
Запускаясь, приложение открывает серверный сокет в потоке, и начинает сканировать сеть (определяя её по своему ip), в диапазоне от 0 до 255, с найденными в отдельном потоке открывает соединение.
формируется список ip'шников. После ввода нужного ip (аля выбор игрока), ему посылается команда и если на неё ответили, начинается партия (морской бой).
Остался вопросик...
Сеть сканируется очень медленно, можно ли установить время в течении которого приложение пытается подсоединиться, ну например, 1 секунда на 1 адрес?
SetTimeout вроде делает не то...
PM MAIL   Вверх
webrider
  Дата 30.12.2010, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Проблему решил, сделав попытку подключения в отдельном потоке.
Проблемы решены, дальше только нужно сделать всё красиво. 
Тему крою. Всех с Наступающим!smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.0604 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.