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


Автор: Kero 2.12.2006, 15:00
Здравствуйте толпа программеровsmile!
Я засел за Java и начал создавать сетевой чат.Возникло много трудностей,возможно связанных с моим незнанием языка,которые нужно обойти.У меня к знающим есть вопрос:Как лучше реализировать чат,для того,чтоб его можно было протестировать у себя на машине с использованием сервера(напр. Apache)?
Жду ответов)

Автор: shimopus 2.12.2006, 15:13
а что за чат на Apache? Или это должен быть веб-чат?

Автор: Kero 2.12.2006, 19:17
в смысле как-то семулить сеть на апаче и проверить работу чата.Я привел как пример, я вовсе не подразумеваю его, просто я не имею представления как тестировать сетевой чат на безсетевой машине.

Автор: COVD 2.12.2006, 21:49
Запускаете на своей машине сервер (Апач, Томкат,..). Открываете на этой же машине браузер и в адресе указываете http://127.0.0.1 или http://localhost . Ваш браузер пошлет запрос на ваш локальный сервер. 

Автор: hovex 5.12.2006, 12:30
я не понял, ето будет чат с клинетом и сервером, или простой вебчат?
Если веб чат, то напиши свои сервер запускай на машине...
создай саитик, где будет работат апплет, который будет связоватся с твоим сервером(програма которая слушает некий порт) и настраивай Java Police  чтобы апплет смог открыват сокет соеидениние...
Аплет будет послат сообшение серверу, а тот в свою очередь к собеседнику...

Но самое главное серверная програма и appache  должны работать обезятельно на одном и том же компутере.. 

Автор: Kero 6.12.2006, 22:05
С апплетиком я понял как делать)
Моя задача создать чат в Java.Swing оболочке,как приложение ,без участия апплета.Как тут лучше поступить?

Автор: LSD 7.12.2006, 19:12
Цитата(Kero @  6.12.2006,  22:05 Найти цитируемый пост)
Моя задача создать чат в Java.Swing оболочке,как приложение ,без участия апплета.Как тут лучше поступить?

В чем проблема?

Автор: Kero 9.12.2006, 13:22
Большая.
Я не знаю как его протестировать в домашних условиях.
К примеру как по сети или в локальном компютере найти ВСЕ окна,которые есть чаты,и соединится с ними.

Автор: Kero 9.12.2006, 18:17
Решено-как-то проверил.
Теперь огромная проблемка:Я делаю ServerSocket с портом своим.Как и предполагалось два чата одновременно не могут юзать один и тот-же порт-выскакивает ошибка мол "Все".Что делать?Каждому чату СВОЙ порт?

Автор: batigoal 10.12.2006, 11:24
Да. Иначе сервер не будет знать, кому из приложений он отправляет ответ - ведь комбинация хоста и порта будут совпадать.

Автор: LSD 10.12.2006, 14:28
Цитата(Kero @  9.12.2006,  18:17 Найти цитируемый пост)
Что делать?Каждому чату СВОЙ порт?

Каждому чат серверу, нужен свой порт. Но никто не запрещает на одном сервере держать несколько каналов.

Автор: Kero 10.12.2006, 15:13
Допустим...
Много портов я сделаю.
Теперь нужно решить мощную проблемму:семулировать сеть и протестить всю связку.С помощью какой софтинки лучше?

Автор: LSD 10.12.2006, 15:20
1. Ты можешь использовать 127.0.0.1
2. Если ты хочешь тестировать реальную сетевую нагрузку, тебе понадобится сесть и несколько компов.

Автор: Kero 10.12.2006, 18:50
Честно-мне все равно нагрузка))))Интересно или оно будет вообще работать)
Ладно.Сеть я найду.Не проблемма)
Пролемка следующая в поиске:как обратится ко ВСЕЙ сети локальной ,и найти там айпихи с работающим моим чатом?

Автор: LSD 11.12.2006, 12:46
Надо послать широковещательный UDP пакет на определенный порт. И все чаты в данной локальной сети должны слушать этот порт, и дать некий отклик на данный пакет.

Автор: Kero 11.12.2006, 23:55
Блин(А без датаграм не получится?Мне родней ТСП)

Автор: Kero 18.12.2006, 22:11
Народ!Ктонить!Подскажите как семулить сеть для теста двух сетевых приложений? 

Автор: BlackStar 19.12.2006, 01:14
Как вариант создать виртуальную машину в VMWare. Но это довольно трудоемко. А вообще можно отладить все на одной машине - не вижу проблемы.

Автор: Kero 19.12.2006, 09:34
Поделись реализацией)

Автор: BlackStar 19.12.2006, 11:03
Реализацией чего?

Вот лучше почитай сначала:

Туториал по сетевым технологиям Java: http://java.sun.com/docs/books/tutorial/networking/index.html
Конкретно по сокетами: http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
Конкретно реализация (и запуск)  клиент-сервера: http://java.sun.com/docs/books/tutorial/networking/sockets/clientServer.html

Автор: Andyb 19.12.2006, 19:11
Это сервер:
Код

import java.io.*;
import java.net.*;
import java.util.*;

public class ThreadedEchoServer
{  
   public static void main(String[] args )
   {  
      try
      {  
         int i = 1;
         ServerSocket s = new ServerSocket(8189);

         while (true)
         {  
            Socket incoming = s.accept();
            System.out.println("Spawning " + i);
            Thread r = new ThreadedEchoHandler(incoming, i);
            Thread t = new Thread(r);
            t.start();
            i++;
         }
      }
      catch (IOException e)
      {  
         e.printStackTrace();
      }
   }
}

/class ThreadedEchoHandler extends Thread

   /**
      Constructs a handler.
      @param i the incoming socket
      @param c the counter for the handlers (used in prompts)
   */
   public ThreadedEchoHandler(Socket i, int c)
   { 
      incoming = i; counter = c; 
   }

   public void run()
   {  
      try
      {  
         try
         {
            InputStream inStream = incoming.getInputStream();
            OutputStream outStream = incoming.getOutputStream();
            
            Scanner in = new Scanner(inStream);         
            PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
            
            out.println( "Hello! Enter BYE to exit." );
            
            // echo client input
            boolean done = false;
            while (!done && in.hasNextLine())
            {  
               String line = in.nextLine();            
               out.println("Echo: " + line);            
               if (line.trim().equals("BYE"))
                  done = true;
            }
         }
         finally
         {
            incoming.close();
         }
      }
      catch (IOException e)
      {  
         e.printStackTrace();
      }
   }

   private Socket incoming;
   private int counter;
}

К нему может коннектитсяа бесконечное число клиентов
данный пример можно обиграть как угодно: SSL, отправка файлов и картинок и тп...
(у меня даже где то исходник такой валялся - как то тоже пытался такое делать - если интересно - пиши)

Автор: Kero 19.12.2006, 22:15
Цитата(Andyb @ 19.12.2006,  19:11)
**К нему может коннектитсяа бесконечное число клиентов
**данный пример можно обиграть как угодно: SSL, отправка **файлов и картинок и тп...
**(у меня даже где то исходник такой валялся - как то тоже **пытался такое делать - если интересно - пиши)

Спасибки за ссылки,но нажаль я на них всех бывал,и мой мультисервер имеет похожую структуру.Я уже все это реализовал,и у меня получается мультиконнект и ост.
Но все же есть загвоздка:мой чат не должен иметь кучу клиентов и один сервер.Чат в себе имеет И сервер И клиент.Он должен:
-Сканить всю локальную сеть на живые коннекты и чаты
-Бродкастить твои сообщения и принимать чужие
-И самое главное-быть одновременно и Сервером И Клиентом.
Задача моя на данный момент состоит в следующем:
Выбрать-ИЛИ TCP , ИЛИ UDP.Всмысле для кайфового бродкаста лучше УДП,а ТСП мне понятней)Ну это уже проблеммы разраба,а сейчас стоит задача в реализации Постоянного сканирования сети на предмет живых чатов.Вот зачем мне эмуляция сети,и совет проффи)
Если заинтиресован - будь добр посоветуй решение)

Автор: LSD 20.12.2006, 14:30
Зачем нужно постоянное сканирование. Пусть лучше при появлениии нового клиента он рассылает пакет, уведомляющий что появился новый клиент. При выключении - пакет, что клиент вышел из сети.
А сам обмен сообщениями можно вести по TCP.

Автор: Andyb 20.12.2006, 14:49
IMHO проще это тогда через UDP делать, но вот надёжней ли...

Автор: BlackStar 20.12.2006, 16:15
Цитата(LSD @  20.12.2006,  14:30 Найти цитируемый пост)
Зачем нужно постоянное сканирование. Пусть лучше при появлениии нового клиента он рассылает пакет, уведомляющий что появился новый клиент. При выключении - пакет, что клиент вышел из сети.А сам обмен сообщениями можно вести по TCP.


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

Автор: Kero 20.12.2006, 22:11
Цитата(BlackStar @ 20.12.2006,  16:15)
Цитата(LSD @  20.12.2006,  14:30 Найти цитируемый пост)
Зачем нужно постоянное сканирование. Пусть лучше при появлениии нового клиента он рассылает пакет, уведомляющий что появился новый клиент. При выключении - пакет, что клиент вышел из сети.А сам обмен сообщениями можно вести по TCP.


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


Именно потому.

Народ-я на UDP вообще не надеюсь-т.к. нужно на 100% знать или пакет дошел,или нет.

LSD - скажи пожалуйста как разослать ВСЕМ пакет о том,что он в онлайне,с помощью TCP,именно всем живым людям в сети?Вот тогда будет мне почти все предельно ясно.

Автор: LSD 20.12.2006, 22:29
Цитата(BlackStar @  20.12.2006,  16:15 Найти цитируемый пост)
Я так подозреваю что постоянное сканирование нужно для отслеживания отвалившихся клиентов. Ведь не всегда же клиент может послать сообщение что он вышел из сети, например случай когда завис или отключили питание.

Для этой цели можно сделать пульс, каждые N секунд посылается спец посылка (при условии, что за этот интервал не было передачи данных), которая сигнализирует, что клиент жив.

Цитата(Kero @  20.12.2006,  22:11 Найти цитируемый пост)
LSD - скажи пожалуйста как разослать ВСЕМ пакет о том,что он в онлайне,с помощью TCP,именно всем живым людям в сети?Вот тогда будет мне почти все предельно ясно.

Широковещательных TCP соединений не существует (в отличие от UDP). Поэтому единственный гарантированный способ, это по очереди соединяться с каждым узлом сети (если они известны, а если нет, то с каждым IP адресом данной подсети).
В чем проблема использовать 2 протокола? UDP - для поиска узлов в сети, TCP для передачи сообщений.

Автор: Kero 20.12.2006, 23:18
Цитата(LSD @ 20.12.2006,  22:29)
Цитата(BlackStar @  20.12.2006,  16:15 Найти цитируемый пост)
Я так подозреваю что постоянное сканирование нужно для отслеживания отвалившихся клиентов. Ведь не всегда же клиент может послать сообщение что он вышел из сети, например случай когда завис или отключили питание.

Для этой цели можно сделать пульс, каждые N секунд посылается спец посылка (при условии, что за этот интервал не было передачи данных), которая сигнализирует, что клиент жив.

Цитата(Kero @  20.12.2006,  22:11 Найти цитируемый пост)
LSD - скажи пожалуйста как разослать ВСЕМ пакет о том,что он в онлайне,с помощью TCP,именно всем живым людям в сети?Вот тогда будет мне почти все предельно ясно.

Широковещательных TCP соединений не существует (в отличие от UDP). Поэтому единственный гарантированный способ, это по очереди соединяться с каждым узлом сети (если они известны, а если нет, то с каждым IP адресом данной подсети).
В чем проблема использовать 2 протокола? UDP - для поиска узлов в сети, TCP для передачи сообщений.

Прекрасно.
Теперь мы подошли к финалу:КАК с помощью UDP найти клиентов в сети за масками типа открыт 2345 порт etc. наиболее максимально еффективно???

Автор: LSD 20.12.2006, 23:49
Что-то наподобие такого:
Код
 // join a Multicast group and send the group salutations
 ...
 String msg = "Hello";
 InetAddress group = InetAddress.getByName("228.5.6.7");
 MulticastSocket s = new MulticastSocket(6789);
 s.joinGroup(group);
 DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(), group, 6789);
 s.send(hi);
 // get their responses!
 byte[] buf = new byte[1000];
 DatagramPacket recv = new DatagramPacket(buf, buf.length);
 s.receive(recv);
 ...
 // OK, I'm done talking - leave the group...
 s.leaveGroup(group);

Автор: Kero 21.12.2006, 12:37
А можна дураку поподробней, как найти все живые адреса в локальной сети, с открытым определенным портом с помощью UDP???
Мне что-то с данного кода не очень понятноsmilesmilesmile

Автор: Kero 27.12.2006, 21:11
...что-то никто не отвечает smile , а у меня время на реализацию тикает...

Автор: JavaCraft 10.2.2007, 17:45
Цитата(LSD @ 20.12.2006,  23:49)
Что-то наподобие такого:
Код
 // join a Multicast group and send the group salutations
 ...
 String msg = "Hello";
 InetAddress group = InetAddress.getByName("228.5.6.7");
 MulticastSocket s = new MulticastSocket(6789);
 s.joinGroup(group);
 DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(), group, 6789);
 s.send(hi);
 // get their responses!
 byte[] buf = new byte[1000];
 DatagramPacket recv = new DatagramPacket(buf, buf.length);
 s.receive(recv);
 ...
 // OK, I'm done talking - leave the group...
 s.leaveGroup(group);

А если в задачу не входит прием ответов по UDP, а нужно только разослать широковещаетльное уведомление. Вторая часть (// get their responses!) не обязательна? Эти ответы, они автоматически генерируются сетевухой или их приложение клиента генерит в ответ на уведомление?
Если приложение клиента, то понятно. Не делать этого на клиенте и всё. А если сетевуха, то что будет?
У меня, например, задача такая. Разослать уведомление и ждать ответов на другом TCP сокете.

Автор: Kero 10.2.2007, 23:35
Спасибо.
Этот сампл с манов я уже давно видел, и все мне показывают.
Я такую фичу уже реализовал-одна проблемка-протестить это у меня дома.У меня нет сети, а проект требует домашнего теста.Без маршрутизатора ,УДП не принимается и не отсылается.
Что делать....

Автор: JavaNewb 28.3.2008, 19:53
А может у кого остались подобные исходники?? Очень было бы кстати посмотреть на эту реализацию!..

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