Форум программистов, компьютерный форум, киберфорум
Наши страницы
Java: Сети
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.68/25: Рейтинг темы: голосов - 25, средняя оценка - 4.68
Coresh DRAW!
2 / 2 / 7
Регистрация: 19.10.2009
Сообщений: 225
1

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

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

Имеется следующий код для чат-сервера, функцией которого является отсылка сообщения от одного юзера всем пользователям, подключенным к чату. Проблема состоит в том, что сообщение принимает только тот клиент, который его послал. В чем ошибка?
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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.11.2011, 11:10
Ответы с готовыми решениями:

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

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

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

Как использовать java.nio.channels.Selector на стороне клиента?
Подскажите пожалуйста (вот уже 3 день бъюсь и не могу решить проблему):...

Сокет, клиент сервер, прокси
Всем доброго времени суток! Есть примитивное приложение типа клиент -...

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

Когда вы пишете из одного буфера многим клиентам, то всякий раз надо делать flip(), т.е. подготовить буфер к повторному использованию. У вас же он один раз отослался и position = limit, т.е. стоит в конце буфера, т.е. для всех последующих посылок буфер выглядит пустым.
0
Coresh DRAW!
2 / 2 / 7
Регистрация: 19.10.2009
Сообщений: 225
02.11.2011, 10:58  [ТС] 4
Спасибо!
0
nnnikotinnn995
5 / 5 / 4
Регистрация: 07.07.2011
Сообщений: 409
03.04.2016, 11:57 5
Цитата Сообщение от mselez Посмотреть сообщение
Когда вы пишете из одного буфера многим клиентам, то всякий раз надо делать flip(), т.е. подготовить буфер к повторному использованию. У вас же он один раз отослался и position = limit, т.е. стоит в конце буфера, т.е. для всех последующих посылок буфер выглядит пустым.
А таким образом не возникнет задержка, если посылать не сообщение, а данные (float boolean...) игрокам онлайн игры?
0
03.04.2016, 11:57
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.04.2016, 11:57

NIO client как отследить что сервер закрыл соединение или произошла потеря связи
Всем добрый день или что там у Вас :) И так, я использую код и семинара...

Как создать сокет сервер с постоянным прослушиванием портов?
Такая вот проблемка. Есть игрушка на флэше, которая отсылает конектится по...

Сервер для игры java+php или java
Всем привет. Возник вопрос следующего характера. Знаю php и java, однако по...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru