Форум программистов, компьютерный форум, киберфорум
Java: Сети
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.66/29: Рейтинг темы: голосов - 29, средняя оценка - 4.66
3 / 3 / 7
Регистрация: 19.10.2009
Сообщений: 225
1

Сокет сервер с использованием Java NIO

01.11.2011, 11:10. Показов 5915. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Имеется следующий код для чат-сервера, функцией которого является отсылка сообщения от одного юзера всем пользователям, подключенным к чату. Проблема состоит в том, что сообщение принимает только тот клиент, который его послал. В чем ошибка?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import java.io.*;
import java.net.*;
import java.nio.*;
import java.util.*;
import java.nio.channels.*;
 
class TestServer
{
  private static final int PORT = 4444;
  private static final int BUFFER_SIZE = 1024;
 
  public static void main(String[] arg)
  {
    try
    {
      // Instead of creating a ServerSocket, create a ServerSocketChannel:
      ServerSocketChannel ssc = ServerSocketChannel.open();
 
      // Set it to non-blocking, so we can use select:
      ssc.configureBlocking(false);
 
      // Get the Socket connected to this channel, and bind it to the listening port:
      ServerSocket ss = ssc.socket();
      ss.bind(new InetSocketAddress(PORT));
 
      // Create a new Selector for selecting:
      Selector selector = Selector.open();
 
      // Register the ServerSocketChannel, so we can listen for incoming connections:
      ssc.register(selector, SelectionKey.OP_ACCEPT);
 
      ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
 
      while(true)
      {
        // See if we''ve had any activity - either an incoming connection,
        //  or incoming data on an existing connection:
        int num = selector.select();
 
        // If we don''t have any activity, loop around and wait again:
        if(num == 0) continue;
 
        // Get the selectedKeys corresponding to the activity
        // that has been detected, and process them
        // one by one:
        Set selectedKeys = selector.selectedKeys();
        Iterator selectedKeysIterator = selectedKeys.iterator();
 
        while(selectedKeysIterator.hasNext())
        {
          // Get a selectedKey representing one of bits of I/O activity:
          SelectionKey selectedKey = (SelectionKey) selectedKeysIterator.next();
 
          // What kind of activity is selectedKeysIterator ?
          if((selectedKey.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT)
          {
            // It''s an incoming connection.
            // Register this socket with the Selector
            // so we can listen for input on selectedKeysIterator:
            Socket s = ss.accept();
 
            // Make sure to make selectedKeysIterator non-blocking, so we can
            // use a selector on selectedKeysIterator:
            SocketChannel sc = s.getChannel();
            sc.configureBlocking(false);
 
            // Register selectedKeysIterator with the selector, for reading:
            sc.register(selector, SelectionKey.OP_READ);
          }
          else if((selectedKey.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ)
          {
 
            SocketChannel sc = null;
 
            try
            {
              // It''s incoming data on a connection, so process selectedKeysIterator:
              sc = (SocketChannel) selectedKey.channel();
 
              // Process the incoming data:
              buffer.clear();
              sc.read(buffer);
              buffer.flip();
 
              // If the connection is dead, then remove selectedKeysIterator
              // from the selector and close selectedKeysIterator
              if(buffer.limit() == 0)
              {
                selectedKey.cancel();
 
                Socket s = null;
 
                try
                {
                  s = sc.socket();
                  s.close();
                }
                catch(IOException ie)
                {
                  System.err.println("Error closing socket " + s + ": " + ie);
                }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.11.2011, 11:10
Ответы с готовыми решениями:

Сервер c использованием Java nio для множества клиентов
Все привет. Недавно познакомился с java nio, и возник такой вопрос при создании сервера для...

Сокет-сервер на JAVA
Всех приветствую. Есть небольшой вопрос по Java. Имеется сокет-сервер на Java следующего вида...

Что оптимальнее для почтового сервиса - java.IO или java.NIO?
Пишу серверную часть мобильного приложения под Android на JDK, в которое будет интегрирован...

Установить java.nio.file
Помогите растыке. как установить java.nio.file? где его скачать? Жал я на

4
3 / 3 / 7
Регистрация: 19.10.2009
Сообщений: 225
01.11.2011, 17:01  [ТС] 2
Ответ найден - при записи буффера в канал происходит блокировка буффера, и последующие каналы не могут его записать. Кто - нибудь знает, как записать один буффер в несколько каналов?
0
0 / 0 / 0
Регистрация: 22.07.2009
Сообщений: 457
01.11.2011, 17:45 3
блокирование - это при записи в буфер, если установлен блокирующий режим

Когда вы пишете из одного буфера многим клиентам, то всякий раз надо делать flip(), т.е. подготовить буфер к повторному использованию. У вас же он один раз отослался и position = limit, т.е. стоит в конце буфера, т.е. для всех последующих посылок буфер выглядит пустым.
0
3 / 3 / 7
Регистрация: 19.10.2009
Сообщений: 225
02.11.2011, 10:58  [ТС] 4
Спасибо!
0
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583
03.04.2016, 11:57 5
Цитата Сообщение от mselez Посмотреть сообщение
Когда вы пишете из одного буфера многим клиентам, то всякий раз надо делать flip(), т.е. подготовить буфер к повторному использованию. У вас же он один раз отослался и position = limit, т.е. стоит в конце буфера, т.е. для всех последующих посылок буфер выглядит пустым.
А таким образом не возникнет задержка, если посылать не сообщение, а данные (float boolean...) игрокам онлайн игры?
0
03.04.2016, 11:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.04.2016, 11:57
Помогаю со студенческими работами здесь

ошибка java.nio.BufferOverflowException
Подскажите пожалуйста что значит эта ошибка? - java.nio.BufferOverflowException Т.е. при попытке...

Производительность Nio и java в целом
Здравствуйте! Задача написать шаблон онлайн соединения на java.nio, который позволяет получать,...

Поясните идеологию Java.nio на примере CharBuffer
Долго думал почему в Java.nio почти все классы абстрактные, а подклассов ни у кого в документации...

Сервер сокет
На этот раз я не спрашиваю, а прошу проверить на правильность. type _clients=record ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru