Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
 Почему DatagramSocket принимает не всё ?  [new]
bobo96
Member

Откуда:
Сообщений: 88
Здравствуйте.
Есть сервер:
public class Server {

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        try(DatagramSocket serverSocket = new DatagramSocket(8888)) {

            while(true) {

                byte[] receiveData =                        new byte[64];
                DatagramPacket receivePacket =              new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);

                executorService.submit(new ConnectThread(receivePacket));

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }

    }

    static class ConnectThread
        implements Runnable {

        private DatagramPacket receivePacket;

        ConnectThread(DatagramPacket receivePacket) {
            this.receivePacket = receivePacket;
        }

        @Override
        public void run() {
            System.out.println(new String(receivePacket.getData()));
        }
    }

}


Есть клиент:
public class Client {

    public static void main(String[] args) {

        send("send1");
        send("send2");
        send("send3");
        send("send4");
        send("send5");
        send("send6");

    }

    private static void send(String str) {

        try(DatagramSocket clientSocket = new DatagramSocket()) {
            clientSocket.send(new DatagramPacket(str.getBytes(), str.getBytes().length,
                 InetAddress.getByName("127.0.0.1"), 8888));
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

}


Запускал 100500 раз, на выходе всегда send1
Остальное почему теряется и как сделать, что бы не терялось ?
Спасибо!
7 мар 19, 10:58    [21827050]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
by-pass
Member

Откуда: Зеленоград (Москва)
Сообщений: 540
Серверный сокет Вы открываете один раз, а клиентский каждый раз.
Порт, скорее всего, еще занят.
7 мар 19, 12:00    [21827153]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
am_sasa
Member

Откуда:
Сообщений: 705
bobo96,

UDP протокол без подтверждения.
Поставь задержку между send, хотя бы 50 млс.
7 мар 19, 12:25    [21827179]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
bobo96
Member

Откуда:
Сообщений: 88
Это было первое, на что я грешил.
Ставил задержку и по 3 сек. результат тот же.
7 мар 19, 12:47    [21827217]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
bobo96
Member

Откуда:
Сообщений: 88
Больше вариантов ни у кого нет ? :(
7 мар 19, 19:52    [21827690]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
Sergunka
Member

Откуда:
Сообщений: 1902
bobo96
Больше вариантов ни у кого нет ? :(


А почему у Вас порты на клиенте и сервере совпадают?
7 мар 19, 23:00    [21827787]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
mayton
Member

Откуда: loopback
Сообщений: 41829
bobo96,

В датаграмных сокетах нет буферизации и повторов. И если принимающая сторона не
Успела среагировать на следующий пакет то он будет потерян.

Почему у тебя происходят потери - пока неясно. Но думаю что детальное логгирование с точностью до микросекунд покажет что некоторые операции принимающая сторона делает не настолько быстро
Как необходимо.
8 мар 19, 00:43    [21827804]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
irbis_al
Member

Откуда: Симферополь
Сообщений: 1533
bobo96,
Я может уже консервативен ...но вот в толк не возьму почему используете лишние элементы
Вот нафиг executorService.submit(new ConnectThread(receivePacket));
Вы же уже объявили Runnable
Почему не классически
(new Thread(new ConnectThread(receivePacket))).start();

Во вложении пример рабочий пример Sender Receiver
(Сфера приминения кода рассылать от сканированной сканером штрихкода(или вес от весов) по сети значение )
Используется гпупповой host 228.5.6.7 Чтоб кричало на всю сеть.
Типа Ис на одном компе весы на другом ,но тот другой получает вес.
Если хотите ограничить только локально в линуксе
файл gedit /etc/sysconfig/network-scripts/route-lo
Добавить строчку
228.5.6.7 via 0.0.0.0 dev lo

Как в винде не знаю.Брэндмаэуром можно ограничить.(Правда в моем опыте иногда проскакивало)

К сообщению приложен файл (flow.tar.gz - 1Kb) cкачать
8 мар 19, 10:05    [21827844]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
mayton
Member

Откуда: loopback
Сообщений: 41829
В приёмнике датаграм-сокета надо в первую очередь принимать пакеты и складывать их в кольцевой буфер.
И эта операция должна быть максимально быстрой. Дальше - уже обрабатывать их как угодно с минимумом
блокировок. И executor даже с 100 и с 1000 потоками нам здесь не помошник.
8 мар 19, 12:42    [21827914]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
bobo96
Member

Откуда:
Сообщений: 88
Всем огромное спасибо!
mayton
В приёмнике датаграм-сокета надо в первую очередь принимать пакеты и складывать их в кольцевой буфер.
И эта операция должна быть максимально быстрой.

Можно чутка подробнее про "принимать пакеты и складывать их в кольцевой буфер. И эта операция должна быть максимально быстрой." ?
8 мар 19, 15:52    [21828008]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
bobo96
Member

Откуда:
Сообщений: 88
irbis_al
Вот нафиг executorService.submit(new ConnectThread(receivePacket));

Как-то давненько один уважаемый человек с этого форума посоветовал подобные вещи вот таким вот образом обрабатывать.
8 мар 19, 15:53    [21828009]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
mayton
Member

Откуда: loopback
Сообщений: 41829
bobo96
Всем огромное спасибо!
mayton
В приёмнике датаграм-сокета надо в первую очередь принимать пакеты и складывать их в кольцевой буфер.
И эта операция должна быть максимально быстрой.

Можно чутка подробнее про "принимать пакеты и складывать их в кольцевой буфер. И эта операция должна быть максимально быстрой." ?

Давай пока отменим буферы.

Новый эксперимент. Давайте толкнем не 6 а 600 сообщений. И закомментарим executor. И добавим счётчик.
Далее по результатам посмотрим.
8 мар 19, 17:25    [21828042]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
Sergunka
Member

Откуда:
Сообщений: 1902
ТС,

разберитесь с портами для начала. Нельзя писать и читать в один порт по контракту для вебсокета на одном IP.

Для примера у меня есть задание, которое мне дали на 4 часа в Сан Франциско написать UDP сервер-клиент посмотрите найдете много для себя интересного - я сам в шоке было дело пять лет назад

https://github.com/SVyatkin/tcp-server-java-example

Код с нио я честно скомуниздил у кого-то крутого перца Вам видимо надо что-то подобное приписать в своем коде

	
               public void handleRead(SelectionKey key) throws IOException {
		// Client socket channel has pending data
		SocketChannel clientChannel = (SocketChannel) key.channel();
		ByteBuffer buf = (ByteBuffer) key.attachment();
		long bytesRead = clientChannel.read(buf);

		if (bytesRead == -1)
			clientChannel.close();
		else if (bytesRead > 0)  {
			System.out.println("bytes:" + bytesRead + ":Message: " + new String(buf.array()));
			key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
		}
	}
8 мар 19, 19:48    [21828099]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
Пылинка
Member

Откуда: СПб
Сообщений: 346
bobo96,
Я сегодня не поленился, копипастнул твой код в два проекта в двух окнах идеи паблик - всё работает.
8 мар 19, 20:01    [21828108]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
bobo96
Member

Откуда:
Сообщений: 88
Еще раз всем огромное спасибо!
Sergunka
разберитесь с портами для начала. Нельзя писать и читать в один порт по контракту для вебсокета на одном IP.

Действительно, перенес клиента на andriod девайс, даже убрал таймаут, в итоге из 300т пакетов не пропал ни один!
А как локально тогда такую конструкцию тестировать, на одной машине и клиент, и сервер, если нет возможности плевать откуда то извне ?
9 мар 19, 10:30    [21828299]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48136
Один на адресе 127.0.0.1, второй на 127.0.0.2 и т.д.
9 мар 19, 15:10    [21828395]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
Sergunka
Member

Откуда:
Сообщений: 1902
bobo96
Еще раз всем огромное спасибо!
Sergunka
разберитесь с портами для начала. Нельзя писать и читать в один порт по контракту для вебсокета на одном IP.

Действительно, перенес клиента на andriod девайс, даже убрал таймаут, в итоге из 300т пакетов не пропал ни один!
А как локально тогда такую конструкцию тестировать, на одной машине и клиент, и сервер, если нет возможности плевать откуда то извне ?


Поставьте разные порты. Контракт IP:port если изменить порт то все должно заработать для вебсокета на одном боксе.

try(DatagramSocket serverSocket = new DatagramSocket(8888))


Просто тупо поставьте

try(DatagramSocket serverSocket = new DatagramSocket(8886))
10 мар 19, 01:09    [21828597]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
mayton
Member

Откуда: loopback
Сообщений: 41829
Sergunka
ТС,

разберитесь с портами для начала. Нельзя писать и читать в один порт по контракту для вебсокета на одном IP.

Какой веб-сокет? Тут вообще тема не про веб-сокеты.

И пример с каналами для tcp-проткола тоже не в тему.
10 мар 19, 01:47    [21828607]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
Sergunka
Member

Откуда:
Сообщений: 1902
mayton
Sergunka
ТС,

разберитесь с портами для начала. Нельзя писать и читать в один порт по контракту для вебсокета на одном IP.

Какой веб-сокет? Тут вообще тема не про веб-сокеты.

И пример с каналами для tcp-проткола тоже не в тему.


https://docs.oracle.com/javase/7/docs/api/java/net/DatagramSocket.html

Не поленился открыл
10 мар 19, 02:24    [21828614]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
Sergunka
Member

Откуда:
Сообщений: 1902
Вот пример про датасокет

https://www.geeksforgeeks.org/java-net-datagramsocket-class-java/

Output : On the client side

IsBound : true
isConnected : true
InetAddress : localhost/127.0.0.1
Port : 5252
Remote socket address : localhost/127.0.0.1:5252
Local socket address : /127.0.0.1:59498
packet sent successfully
Received packet data : [13, 18]
Local Port : 59498
Local Address : /127.0.0.1
SO Timeout : 50


Порты у клиента и сервера разные хотя сидят на одном боксе.
10 мар 19, 02:33    [21828616]     Ответить | Цитировать Сообщить модератору
 Re: Почему DatagramSocket принимает не всё ?  [new]
mayton
Member

Откуда: loopback
Сообщений: 41829
Но у автора с портом нет проблем. Так же как нет проблем с тем исходником на который ты ссылается.

Правда автору незачем на каждое сообщение клиента пересоздавать клиентский сокет. Он может
Использовать один разделяемый объект DatagramSocket и много выделенных DatagramPackets.
10 мар 19, 10:58    [21828659]     Ответить | Цитировать Сообщить модератору
Все форумы / Java Ответить