Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 05.02.2013
Сообщений: 6

Потеря пакетов с селектор сервером

23.03.2013, 22:43. Показов 2071. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте... делаю сервер на одну мморпг игру... сервер реализован по средствам селектора... получает пакеты гладко и считывает с них информацию но когда он должен получить три пакета подряд он получает толко один..ну очень редко и второй помогите пожалуйста... вот код

Code
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
ServerSocketChannel ServerChannel = ServerSocketChannel.open();
    ServerChannel.configureBlocking(false);
    ServerSocket Server = ServerChannel.socket();
    Server.bind(new InetSocketAddress(port));
    Selector selector = Selector.open();
    ServerChannel.register(selector, SelectionKey.OP_ACCEPT);
    System.out.println("Server began listening on port: " + Color.cyan + port + Color.white);
    while (true)
    {
 
      int num = selector.selectNow();
      if (num == 0)
      {
        continue;
      }
      Set<SelectionKey> keys = selector.selectedKeys();
      Iterator<SelectionKey> it = keys.iterator();
 
      while (it.hasNext())
      {
 
        SelectionKey key = it.next();
        if (key.isAcceptable())
        {
          Socket Client = Server.accept();        
          count++;
          SocketChannel ClientChannel = Client.getChannel();
          ClientChannel.configureBlocking(false);
          ClientChannel.register(selector, SelectionKey.OP_READ);//read incoming stream
          ServerLogger.logInfo("Client Connected...." + "you have " + Color.cyan + count + Color.white + "/" + maxcon + " clients connected");
        }
        else if (key.isReadable())
        {
          try
          {
          SocketChannel Client;
          Client = (SocketChannel) key.channel();         
          client = Client;
          PacketProcessor.onPacketRecieve();
          }
          catch(Exception ex)
          {
            if(ex.getMessage().contains("forcibly closed"))
            {            
            count--;
            ServerLogger.logWarning("Client Disconnected...." + "you have " + Color.cyan + count + Color.white + "/" + maxcon + " clients connected");
            key.cancel();
            continue;
            }
          }
        }         
        it.remove();
 
      }
     
    }
п.с. когда в олле ставлю бп на каждый пакет и посылаю с паузой тогда норм...получается мой сервер медленный?

Добавлено через 2 часа 7 минут
помогите кто нибудь!!... сервер получает только один пакет если к нему идут 3 одновременно
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.03.2013, 22:43
Ответы с готовыми решениями:

Потеря 50% пакетов через роутер и отброс пакетов
Добрейшего времени суток , имеется проблема - потеря пакетов стремящаяся к 50% через роутер (eltex NTU-RG-1402G-W),выглядит это сначала как...

Потеря пакетов Wi-fi
Ноут asus rog g751j Роутер tp-link tl-wr841n(новый, настроен и работает нормально) Скорость соединения через вайфай 30/30, скорость...

Потеря пакетов
У меня настроен интернет через VPN (так как живу в общежитии). ОС: Win7. Проблема в том, что у меня подвисает интернет, хотя раньше...

13
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
23.03.2013, 23:44
он у вас однопоточный просто, хапанул один пакет и пока не переварит других даже не слушает
надо сделать несколько потков или динамически подымать потоки

примерно так:

Java
1
2
while (true)
        new ServerThread(serverSocket.accept()).start();
0
0 / 0 / 0
Регистрация: 05.02.2013
Сообщений: 6
23.03.2013, 23:55  [ТС]
можно более подробно?
а без threadов нельзя обойтись?
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
24.03.2013, 00:06
без потоков никак, пока один сокет занят, он не может слушать других клиентов

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

вот вам пример от оракла http://docs.oracle.com/javase/... erver.html
0
0 / 0 / 0
Регистрация: 05.02.2013
Сообщений: 6
24.03.2013, 01:03  [ТС]
Цитата Сообщение от mutagen Посмотреть сообщение
без потоков никак, пока один сокет занят, он не может слушать других клиентов
помойму вы меня не поняли....проблема не в том что только один клиент может подключится...ето какраз работает(даже три подключал) проблема в том что когда он слушает пакеты данного клиента и клтент посылает несколько сообшений подряд..тогда потери

вот так:

Client->Server-получил

Server->Client

Client-->server-получил
Client-->Server- не получил 90%
Client-->Server- не получил вообше
....problema tut
Server->Client ответ на первый

Добавлено через 1 минуту
вот еще кода обработки:

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
public static void onPacketRecieve() throws Exception
  {
    ByteBuffer buff = ByteBuffer.allocate(2048);
    byte[] packet = buff.array();
    int open=Server.client.read(buff);
    if(open!=-1)
    {
    new ClientPacket(packet);
    ServerLogger.logInfo("Recieved Packet From Client: <-" + Server.client.getRemoteAddress());
    PacketHandler.execute();
    }
  }
public static void execute() throws Exception
  {   
    if (ReadOpcode() == PacketOpcodes.HandshakePacket.getValue())
    {
      switch (ReadId())
      {
        case 0x01:
          CP_ClientHello.read();
         break;
        case 0x10:
          CP_ClientKeyExchange.read();
         break;
      }
    }
    else if (ReadOpcode() == PacketOpcodes.Change_Cipher_Spec.getValue())
    {
      CP_ChangeCipherSpec.read();
    }
    else if (ReadOpcode() == PacketOpcodes.ServerError.getValue())
    {
      CP_ServerError.read();
    }
    else
    {
      CP_XmlRequest.read();
    }
  }
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
24.03.2013, 03:46
Цитата Сообщение от el_falcon Посмотреть сообщение
помойму вы меня не поняли
помоЙму это вы непоняли 1 сокет не может слушать 3 клиента одновременно

Добавлено через 39 минут
сервер
Кликните здесь для просмотра всего текста
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
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
 
public class HelloClient {
 
    public static void main(String[] args) throws Exception {
 
        for (int i = 0; i < 10; i++) {
            String req = "Hello num " + i;
            SocketChannel clientChannel = SocketChannel.open();
            clientChannel.connect(new InetSocketAddress(HelloServer.PORT));
            new ClientThread(req, clientChannel).start();
        }
 
    }
 
    static class ClientThread extends Thread {
        private String request;
        private SocketChannel channel;
 
        public ClientThread(String request, SocketChannel channel) {
            super();
            this.request = request;
            this.channel = channel;
        }
 
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                send(request + " iteration " + i + "\n");
            }
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
        void send(String request) {
            byte[] data;
            try {
                data = request.getBytes("UTF-8");
                ByteBuffer buffer = ByteBuffer.wrap(data);
                while (buffer.hasRemaining())
                    channel.write(buffer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}


и клиент

Кликните здесь для просмотра всего текста
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
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
 
public class HelloClient {
 
    public static void main(String[] args) throws Exception {
 
        for (int i = 0; i < 10; i++) {
            String req = "Hello num " + i;
            SocketChannel clientChannel = SocketChannel.open();
            clientChannel.connect(new InetSocketAddress(HelloServer.PORT));
            new ClientThread(req, clientChannel).start();
        }
 
    }
 
    static class ClientThread extends Thread {
        private String request;
        private SocketChannel channel;
 
        public ClientThread(String request, SocketChannel channel) {
            super();
            this.request = request;
            this.channel = channel;
        }
 
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                send(request + " iteration " + i + "\n");
            }
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
        void send(String request) {
            byte[] data;
            try {
                data = request.getBytes("UTF-8");
                ByteBuffer buffer = ByteBuffer.wrap(data);
                while (buffer.hasRemaining())
                    channel.write(buffer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

ничего не теряется
0
0 / 0 / 0
Регистрация: 05.02.2013
Сообщений: 6
24.03.2013, 19:43  [ТС]
понял в чем проблема...я задал моему байт буфферу слишком большой размер 2048 бай...когда одно временно три пакета все три записываются в буффер...как мне зделать один буфф на пакет или буфф с динамичным размером? в заголовке пакета имеется его длина...подскажите плз
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
24.03.2013, 22:29
Цитата Сообщение от el_falcon Посмотреть сообщение
когда одно временно три пакета все три записываются в буффер...
почему же вы так уверены что все клиентские потоки одновременно могут быть прочитаны сокетом сервера?

для проверки сделайте в коде сервера что я дал вот такую замену (превратив его в однопоточный таким образом)
Java
1
2
3
4
5
//      while (true) {
            SocketChannel clientChannel = serverChannel.accept();
            HelloServerThread helloServerThread = new HelloServerThread(clientChannel);
            helloServerThread.start();
//      }
и запустите мультипоточных клиентов, вы сразу увидите что 1 клинт смог передать без проблем все свои 3 пакета,
а вот остальные вылетят с эксепшенами
Вот когда вы мне сможете сказать почему они вылетели, тогда и поговорим про динамический буфер
0
0 / 0 / 0
Регистрация: 05.02.2013
Сообщений: 6
25.03.2013, 02:48  [ТС]
я уверен что все три пакета в буферре поскольку написал маленькую функц которая показывает содержымое буффера в консоли...и действительно они были тесно пределаны друг к другу
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
25.03.2013, 03:14
Цитата Сообщение от el_falcon Посмотреть сообщение
я уверен что все три пакета в буферре поскольку написал маленькую функц которая показывает содержымое буффера в консоли...и действительно они были тесно пределаны друг к другу
покажите на примере кода, как у вас это вышло
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
25.03.2013, 17:10
Цитата Сообщение от mutagen Посмотреть сообщение
покажите на примере кода, как у вас это вышло
Ну, это-то понятно, как вышло. С одной стороны потоком пишут, с другой читают. Несколько записей сливаются в одно чтение. Всё логично, работаем-то с потоками!

Автор, Вам придется эмулировать свой протокол, если хотите сообщения различать. Либо маркеры начала и конца, либо тривиально - размер (4 байта)+сообщение+размер второго сообщения (4 байта)+сообщение+... считываете 4 байта, делаете из них int, считываете полученное количество байтов, повторяете по мере необходимости.
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
26.03.2013, 02:19
Цитата Сообщение от Skipy Посмотреть сообщение
С одной стороны потоком пишут, с другой читают.
ТС утверждает что клинтских потоков несколько, вот мне и интересно как он с мультипотоков на 1 сокет умудрился писать
(это к тому что на одной jvm с клиентских мультипотоков один порт не биндится, или биндится? Скипи как думаешь?)
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
26.03.2013, 12:01
Цитата Сообщение от mutagen Посмотреть сообщение
ТС утверждает что клинтских потоков несколько, вот мне и интересно как он с мультипотоков на 1 сокет умудрился писать
ТС утверждает вот что:

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

(это к тому что на одной jvm с клиентских мультипотоков один порт не биндится, или биндится? Скипи как думаешь?)
У каждого клиента порт свой, на сервере - один. Потоки данных идентифицируются парами портов клиента/сервера, насколько я понимаю.

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
package ru.skipy.tests;
 
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
 
/**
 * ClientServerTest
 *
 * @author Eugene Matyushkin aka Skipy
 * @since 26.03.13
 */
public class ClientServerTest {
 
    public static void main(String[] args) throws Exception{
        Thread server = new Thread(new Server(), "server thread");
        server.start();
        Socket s = new Socket("localhost", 12345);
        System.out.println("Connecting to "+s.getPort()+" (localPort="+s.getLocalPort()+
                ") remote address="+s.getRemoteSocketAddress());
        int data = new Random().nextInt() & 0xff;
        System.out.println("sending: "+data);
        s.getOutputStream().write(data);
        s.close();
    }
 
    static class Server implements Runnable{
 
        @Override
        public void run(){
            try{
                ServerSocket ss = new ServerSocket(12345);
                System.out.println("Listening on "+ss.getLocalPort());
                Socket s = ss.accept();
                System.out.println("Accepted on "+s.getPort()+" (localPort="+s.getLocalPort()+") remote address="+
                    s.getRemoteSocketAddress());
                int data = s.getInputStream().read();
                System.out.println("read: "+data);
                s.close();
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }
}
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
26.03.2013, 14:16
Цитата Сообщение от Skipy Посмотреть сообщение
...ето какраз работает(даже три подключал)
3 последовательно или 3 параллельно, вот что народ интересует.
то что он не может разделиться на сегменты данных это уже понятно было ещё в первом посте.
меня интересует как он разделять собирается микс из допустим 3 клиентов и 3 пакетов от каждого.
По твоим словам ему на 1 поточный сервер успешно могут прийти в миксе 9 пакетов и он их успешно скушает.
Тогда я начинаю переставать понимать архитектуру при таком сраче с пакетами
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.03.2013, 14:16
Помогаю со студенческими работами здесь

Потеря пакетов
Добрый день, мой компьютер получает интернет по такой схеме Модем 4G воткнут в роутер, роутер раздаёт вайфай, Нетбук ловит его и по...

Потеря пакетов
Начались потери пакетов в онлайн игре. Лаги, плохо работает. Сделал тест соединения. Я не специалист, но вроде бы потери происходят на...

Потеря пакетов
Здравствуйте, недавно обнаружил у себя такое явление, как потеря пакетов (при помощи программы ping plotter). Как можно вылечить?

Потеря CAN пакетов
Добрый день. У меня есть STM32F4 подключенный к линуксу по шине CAN. Линукс посылает команды а stm их выполняет. Также линукс постоянно...

Потеря пакетов
Такая проблема. Начал подлагивать интернет, через командную строку проверил потерю пакетов. Выяснилось, что стабильно, интервалом...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 30.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru