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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рассылка сообщения всем клиентам SocketServer, миничат 
:(
    Опции темы
brave
Дата 19.10.2012, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброго времени суток. Пишу небольшой чат, но не получается сообщение с сервера отослать всем клиентам. Записываю клиентские сокеты в коллекцию при создании, а потом в цикле вытягиваю с коллекции и отсылаю сообщение принятое на вход сервера - не работает. Слышал, что эта задача реализуется с помощью паттерна Observer, но хотелось бы разобраться, где просчет в моем примере. Всего 4 класса(пока что):

Chat.java - сервер
Код

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

public class Chat {

    public static void main(String[] args)
    {
        try
        {
            int i = 1;
            ServerSocket server = new ServerSocket(PORT);
            System.out.println("The server has been started.");
            while (true)
            {                
                Socket incoming = server.accept();
                ServerThreads serverRun = new ServerThreads(incoming);
                Thread t = new Thread(serverRun);
                t.start();
                System.out.println("Thread" + i);
                i++;
            }
            
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    
    private final static int PORT = 1234;
}




ServerThreads.java - объект Runnable
Код

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


public class ServerThreads implements Runnable
{
    public ServerThreads(Socket incoming)
    {
        this.incoming = incoming;
    }
    
    public void run()
    {
      try
      {
          try
            {   
                
                SocketList.addSocketToList(incoming);
                InputStream inStream = incoming.getInputStream();
                OutputStream outStream = incoming.getOutputStream();
                
                Scanner in = new Scanner(inStream);
                PrintWriter out = new PrintWriter(outStream, true);
                
                out.println("You have connected to the server. Enter BYE to exit.");
                                
                boolean done = false;
                while (!done && in.hasNextLine())
                {
                    String line = in.nextLine();
//                    System.out.println(line);
                    for (Socket s : SocketList.getSocketList())
                    {
                        new PrintWriter(s.getOutputStream()).println(line);
                    }
                    
                    if (line.trim().equals("BYE")) done = true;
                }
            }
            finally
            {
                incoming.close();
                SocketList.removeSocketFromList(incoming);
            }
      }    
        
      catch(IOException e)
      {
        e.printStackTrace();
      }
        
    }
    
    private Socket incoming;
}



Client.java - Клиент
Код

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


public class Client 
{
    public static void main(String[] args)
    {
     try
     {
         Socket client = new Socket(SERVER, PORT);
         if (client != null) System.out.println("Socket has been created successfully.");
         
         InputStream inStream = client.getInputStream();
         OutputStream outStream = client.getOutputStream();
         
         Scanner in = new Scanner(inStream);
         PrintWriter out = new PrintWriter(outStream, true);
         
         String line = in.nextLine();
         System.out.println(line);

         Scanner cmd = new Scanner(System.in);
         
         while (true)
         {
          String cmdLine = cmd.nextLine();
          String serverLine = in.nextLine();
          out.println(cmdLine);
          System.out.println(serverLine);
                   
          if (cmdLine.trim().equals("BYE"))
          {
              System.out.println("Connection has been closed.");
              client.close();
              System.exit(0);
          } 
         }
            
     }
     catch(IOException e)
     {
         e.printStackTrace();
     }
    }
    
    private static final String SERVER = "localhost";
    private static final int PORT = 1234;
}



SocketList.java - коллекция сокетов
Код

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


public class SocketList 
{
   public synchronized static LinkedList<Socket> getSocketList()
   {
       return socketList;
   }
   
   public synchronized static void addSocketToList(Socket s)
   {
       socketList.add(s);
   }
   
   public synchronized static void removeSocketFromList(Socket s)
   {
       socketList.remove(s);
   }
   
   private static LinkedList<Socket> socketList = new LinkedList<Socket>();
}

PM MAIL   Вверх
brave
Дата 19.10.2012, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



У меня возникает два сомнения:

1. Имеет ли вообще смысл сохранять сокеты в коллекцию? 

из ServerThreads.java:
Код

SocketList.addSocketToList(incoming);


Оно вообще будет работать, если я его потом из коллекции вытяну, возьму OutputStream и отправлю сообщение в этот поток. Это сообщение придет клиенту?

из ServerThreads.java:
Код

while (!done && in.hasNextLine())
                {
                    String line = in.nextLine();
                    for (Socket s : SocketList.getSocketList())
                    {
                        new PrintWriter(s.getOutputStream()).println(line);
                    }
                    
                    if (line.trim().equals("BYE")) done = true;
                }


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

из Client.java:
Код

 Scanner in = new Scanner(inStream);
         PrintWriter out = new PrintWriter(outStream, true);
         
         String line = in.nextLine();
         System.out.println(line);
         Scanner cmd = new Scanner(System.in);
         
         while (true)
         {
          String cmdLine = cmd.nextLine();
          String serverLine = in.nextLine();
          out.println(cmdLine);
          System.out.println(serverLine);
                   
          if (cmdLine.trim().equals("BYE"))
          {
              System.out.println("Connection has been closed.");
              client.close();
              System.exit(0);
          } 
         }


Это сообщение отредактировал(а) brave - 19.10.2012, 15:56
PM MAIL   Вверх
brave
Дата 22.10.2012, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Решил попробовать собирать в коллекцию не сокеты, а потоки. Только застрял на вопросе, как отослать сообщение потоку. Написал вот такой вот метод:

Код

public void broadcastMessage(String message)
    {
        for (int i = 0; i < Chat.getList().size(); i++)
        {
            ClientHandler ch = Chat.getList().get(i);  // получаем элемент LinkedList<ClientHandler> коллекции
            Socket incoming = ch.getSocket();  //  получаем сокет, переданный в конструктор ClientHandler при создании
            try 
            {
                try
                {
                OutputStream outStream = incoming.getOutputStream();
                PrintWriter out = new PrintWriter(outStream, true);
                out.println(str);
                }
                finally
                {
                    incoming.close();
                }
            } 
            catch (IOException e) 
            {        
                e.printStackTrace();
            }
        }
    }


Вроде как должно работать, но не работает... Может кто знает, в чем проблема?
PM MAIL   Вверх
brave
Дата 23.10.2012, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Отредактировал, теперь сообщение, которое пришло на сервер, отсылается всем клиентам подключенным к серверу, но...  появилась некая очередь сообщений на сервере и клиент не может получить сообщение пока сам не отправит. Например, первый клиент пишет hi, ему сразу это hi возвращается, а второй ничего не получит пока сам не напишет что-то и т.д. Я думаю, что дело в методе клиента, который слушает поток с сервера и поток с клавиатуры:

Код

while (in.hasNextLine() || keyboard.hasNextLine())
            {
                if (in.hasNextLine())
                {
                    String line = in.nextLine();
                    System.out.println(line);
                }
                if (keyboard.hasNextLine())
                {
                    String keyboardLine = keyboard.nextLine();
                    out.println(keyboardLine);
                    if (keyboardLine.trim().equals("BYE")) System.exit(0);

                }                
            }    


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

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

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


 




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


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

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