Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
1 / 1 / 0
Регистрация: 19.10.2021
Сообщений: 51
.NET 6

Задержка получения пакетов

10.11.2023, 17:56. Показов 1438. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Есть игровой сервер, запущен с тикрейтом 70, получает от одного игрока примерно 62 пакета в секунду. Но возникае задержка в рассылке пакетов остальным игрокам, около секунды, а если убрать
C#
1
await Task.Delay(1000 / TickRate);
или установить 500, то задержка пропадает. метод запускается в отдельном потоке через Task.Run для каждого игрока.

C#
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
 private async void ReceiveLoop(Player player)
        {
            IPEndPoint udpEndPoint = new (player.TCPClientEndPoint.Address, player.UdpPort);
            UdpClient udp = player.UdpClient;
            TcpPacketProtocol tcpPacketProtocol = player.TcpProtocol;
            TcpClient tcp = player.TCPClient;
 
            player.LastSendInfoPacket = DateTime.Now;
            player.LastReceivedPacket = DateTime.Now;
 
            while (player.Connected)
            {
                try
                {
                    if (udp != null && udp.Available > 0)
                    {
                        byte[] udpBuffer = udp.Receive(ref udpEndPoint);
                        HandlePackets(udpBuffer, player);
                    }
 
                    if (tcp != null && tcp.Available > 0)
                    {
                        byte[] tcpBuffer = tcpPacketProtocol.Receive();
                        HandlePackets(tcpBuffer, player);
                    }
 
                    if ((DateTime.Now - player.LastReceivedPacket).TotalMilliseconds > MaxAskTimeForCheckConnection)
                    {
                        DisconnectClient(player);
                        break;
                    }
 
                    if (player.PacketManager != null)
                    {
                        if ((DateTime.Now - player.LastSendInfoPacket).TotalMilliseconds > 500)
                        {
                            player.PacketManager.SendPacket(new ServerInfo(player.Ping, PlayersCount));
                            player.LastSendInfoPacket = DateTime.Now;
                        }
                    }
                }
                catch (SocketException ex) when (ex.ErrorCode == 10054)
                {
                    DisconnectClient(player);
                    break;
                }
                catch (SocketException ex)
                {
                    Console.WriteLine($"Error receiving data: {ex}");
                    DisconnectClient(player);
                    break;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    DisconnectClient(player);
                    break;
                }
 
                await Task.Delay(1000 / TickRate);
            }
        }
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.11.2023, 17:56
Ответы с готовыми решениями:

Задержка пакетов UDP
Всем добрый день, не нашёл на просторах интернета ответа на свой вопрос, по этому хочу спросить у вас, надеюсь на ответ. ...

SharpPcap Перехват и задержка пакетов
Как, используя SharpPcap, можно перехватить пакет на локальной машине до его отправки и, исходя из значения переменных, отправить сразу,...

Программа для получения пакетов данных
Народ подскажите мануалы инфу ссылки, да вообще хоть чтонибудь... Хочу напрогать приложение которое будет показывать всю информацию...

33
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
12.11.2023, 10:17
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Unity123 Посмотреть сообщение
TCP нужен для отправки каких-то важных событий, по типу пакета с данными для входа
эм... вот вообще не стоит так делать. Проблем просто вагон:
- нужно синхронизировать два(!) подключения. Т.е. когда первое отвалилось, нужно закрывать второе. Причем если TCP ещё худо-бедо понятно когда отвалится, то вот UDP всегда завязан на таймауте самописного ping-pong. У вас очень вероятно будет проблема что "отвилался чат" или "игра перестала отвечать, но чат работает"
- TCP и UDP будут конкурировать друг с другом. Причем TCP это такой зверь, который на потери пакетов генерит дополнительный трафик. А потери пакетов, это очень часто когда в конкретном месте происходит перегрузка трафика, и выходит что ваш TCP будет по сути только усугублять проблему
- две реализации ping-pong: внутренняя для TCP, от которой вы никуда не денетесь, и самописная на udp. Т.е. будете выполнять однотипное действие дважды, плюс трафик бонусом.
- сокеты -- конечный ресурс на ПК. x2 сервере для двух протоколов не особо хорошее решение.

Грубо говоря вы похерите всё преимущество UDP, при этом многократно усложнив код. При этом реализовать подтверждение на UDP несложно: добавляем уникальный индекс и после отправки ждем N ms подтверждение получения. Повторяем M раз, если нет -- выдаем ошибку.

Не по теме:

P.S. честно, без обид, но вам явно нужно сейчас не кодить, а читать кучу материала по том как всё это организовывать в играх. Пока явно видно что вы очень скудно разбираетесь в том, как работать что с TCP, что с UDP. Попытки интуитивно решить вопрос -- не всегда хорошо. Один только факт что вы хотите реализовать внутри TCP ping-pong... ну, это блин полный треш. Типа "я засунул мороженое в холодильник, а потом холодильник выкидываю на мороз, чтобы явно не растаяло".

Сама архитектура, где udp и tcp скинут в кучу в рамках одного метода, это нонсенс. Типа пока не считали из TCP потока, UDP сокет сидит ждет. Это вот 100500% нужно разносить, даже если решите таки использовать два протокола.

Щас ещё обратил что у вас проверка tcp.Available > 0, которая приведет к тому что ваш цикл будет в режиме ожидания молотит шо дурной, генеря бессмысленную нагрузу сопоставимую с while(true) { /* нет действий, но из цикла не выходим*/ }

Плюс как я говорил выше: стоит уточнить у знающих людей, которые занимались именно проектированием игр (желательно что-то посложнее "три в ряд"). Можно конечно включить режим "да нормально всё будет, у всех хороший интернет", а потом узнать что игра -- УГ, лагает, вылетает и всё в таком духе.

Как минимум стоит задуматься, почему все нормальные игры используют либо UDP (причем по нему шурует вот вообще весь трафик), либо TCP (пошаговым играм -- самое оно), но вместе это не комбинируют. Я думаю это явно не спроста.

0
1 / 1 / 0
Регистрация: 19.10.2021
Сообщений: 51
12.11.2023, 10:25  [ТС]
Цикл приема уже разделил на два, для TCP и для UDP, там уже циклы не "молотят", насчёт комбинирования, услышал, видел, есть библиотеки Reliable Udp, так что прием данных не сложно изменить, ну схема с комбинированием вроде рабочая, SAMP написан на Raknet, а там как раз комбинируются протоколы

Добавлено через 1 минуту
Пинг-понг всё-равно несет полезную нагрузку, в виде обновления данных о количестве игроков, пинге, серверном времени, думаю, что это не сильно большая проблема
0
12.11.2023, 10:40

Не по теме:

Ну, я пытался. Хотя если стоит задача повторить дyх gta online, где тот ещё треш в плане оптимизации и защиты от читеров -- данный подход имеет право на жизнь. :)

0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
12.11.2023, 15:49
Если в сетевом пути существует узкое место, то оно равнозначно существует для обоих протоколов. В случае с TCP - протокол справится сам, со всеми своими пере-отправками. UDP - пакеты тупо будут потеряны, если не реализовано обратной связи на уровне приложения, что дополнительно вносит накладные расходы по времени.
На выбор влияет много факторов, в том числе размер посылки. Если он относительно не большой, то TCP выиграет в большинстве случаев.
Цитата Сообщение от Wolfdp Посмотреть сообщение
что ваш TCP будет по сути только усугублять проблему
Опять же, смотря с какой стороны смотреть. Либо мы из 20-ти потерянных пакетов вернем 10 и продолжим, либо потеряем все 20 и продолжим с более длительного ощутимого "скачка". Здесь уже возникает некий баланс, выбор давления на плечи которого зависит от конкретной ситуации - либо потерять время, либо "качество". Ну и опять все упирается в размер и частоту значимых для клиента передач.

В любом случае, не понимая принципов этих двух вариантов и необходимой базы для их правильного использования в своем приложении - пользы не принесет ни тот ни другой.
0
1 / 1 / 0
Регистрация: 19.10.2021
Сообщений: 51
12.11.2023, 16:42  [ТС]
Всё-таки стоит комбинировать два протокола? TCP нужен для чата, действий с диалоговыми окнами, создание, удаление машин и игроков вне зоны стрима, используется событийно и нет большого потока данных, пакеты весят до 100 байт, по tcp наверно пакетов 5 в секунду. Оставить два протокола или писать свой «надежный» udp?
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
12.11.2023, 16:52
Цитата Сообщение от Unity123 Посмотреть сообщение
Всё-таки стоит комбинировать два протокола?
Я могу дать точный и однозначный ответ, но это тебе ничего не даст. Если понимания TCP/UDP нет, то в любом случае, скорее всего, твой код будет неэффективен.
Проникнись сперва теорией более углубленно и попробуй сделать выбор сам.
0
1 / 1 / 0
Регистрация: 19.10.2021
Сообщений: 51
12.11.2023, 16:55  [ТС]
Ну тут пишут, что tcp будет трафик весь забирать, а вы наоборот, говорите, что если есть слабое место в сети, то скажется на оба протокола, мне от tcp нужна только гарантия доставки и доставка пакетов в правильном порядке, в таком случае лучше свой протокол писать поверх udp? Или же буду накладные расходы на уровне приложения?
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
12.11.2023, 17:07
Unity123,
1. Никто не знает что ты там передаешь и получаешь обратно.
2. Неизвестна необходимая реакция участников на перебой с данными
3. Если сетевой радиус "улица/город" - один подход, если Москва - Австралия, другой.
и пр. вещи...

Если объем траффика ~100 байт да еще и с интервалами, описанными выше, то TCP за глаза, в обе стороны.
Но, чувствую, и с этим будут проблемы, т.к. любые преимущества того или иного протокола можно легко запороть неумелыми действиями в своем коде, в связи с отсутствием знаний.
0
1 / 1 / 0
Регистрация: 19.10.2021
Сообщений: 51
12.11.2023, 17:14  [ТС]
1. Передаются данные о чате, события посадки/высадки в авто, удаление и создание транспорта/игроков, ответы на диалоговые окна, и другие события, которые происходят не каждую секунду
2. Некоторым данным по типу чата при потере пакета нужно ждать, пока его переотправят, остальным нужна только гарантия доставки
3. Расстояния большие могут быть
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3463 / 2784 / 575
Регистрация: 04.09.2018
Сообщений: 8,757
Записей в блоге: 3
12.11.2023, 17:25
Unity123, сделай, для начала, хотя бы что-то одно. Задумка "грандиозная", а как сделать понимания нет. Далеко не уедешь.
0
1 / 1 / 0
Регистрация: 19.10.2021
Сообщений: 51
12.11.2023, 17:26  [ТС]
Уеду, спасибо за внимание

Добавлено через 51 секунду
Одно уже сделано месяца три назад, сейчас конкретно спрашиваю, как будет лучше
0
 Аватар для IamRain
4695 / 2702 / 735
Регистрация: 02.08.2011
Сообщений: 7,236
13.11.2023, 05:21
Цитата Сообщение от Unity123 Посмотреть сообщение
Всё-таки стоит комбинировать два протокола? TCP нужен для чата, действий с диалоговыми окнами, создание, удаление машин и игроков вне зоны стрима, используется событийно и нет большого потока данных, пакеты весят до 100 байт, по tcp наверно пакетов 5 в секунду. Оставить два протокола или писать свой «надежный» udp?
Как хотите. Насколько я знаю, во многих стриминговых сервисах + VoIP используются связки протоколов в два канала, один - для траффика (RTP), второй - сигнальный протокол (SIP).
Для затравки я бы порекомендовал полистать книгу "Многопользовательские игры. Разработка сетевых приложений" - тут можно подсмотреть, как лучше дробить прикладную сетевую логику для оптимального быстродействия и пользовательского опыта.
0
1 / 1 / 0
Регистрация: 19.10.2021
Сообщений: 51
13.11.2023, 05:23  [ТС]
Интересно, прочитаю, спасибо
0
 Аватар для IamRain
4695 / 2702 / 735
Регистрация: 02.08.2011
Сообщений: 7,236
13.11.2023, 05:56
Цитата Сообщение от Unity123 Посмотреть сообщение
while (player.Connected)
Не знаю как реализовано там внутри, но я бы не стал проверять свойство TcpClient.IsConnected - оно ненадежно.
Разрыв соединения проверяется только через получение пакетов с данными (Receive*-операции) с помощью try/catch.

Цитата Сообщение от Unity123 Посмотреть сообщение
tcp.Available > 0)
Это тоже лишнее, это проверка на наличие данных в receive буфере. Такие проверки могут часто возвращать false (если получатель быстро разгребает данные) и ваш вечный цикл будет продолжать крутится, то есть это загружает CPU.

Добавлено через 27 минут
Цитата Сообщение от IamRain Посмотреть сообщение
то есть это загружает CPU.
Поэтому лучше замыкаться на IO, а не на CPU, чтобы не было ненужной холостой работы процессора.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.11.2023, 05:56

Приодический лаг во время получения UDP пакетов на Android
К смартфону по WIFi подключено устройство, которое отправляет UDP пакеты, среднее время получения пакета 5мс, однако, периодически, каждые...

Сокет для получения udp пакетов с определенным портом
Добрый день Нужно написать сокет, который прослушивал бы определенный порт и получал пакеты, которые ему адресованы. Сообщения идут на ...

Получения пакетов "халявной" информации.
Есть настроенный приём со спутника SpectrumSat 39*В.Д., т.е. ассиметричный спутниковый интернет. Господа программисты, где скачать...

Задача передачи пакетов данных: смоделировать процесс обслуживания 5000 пакетов
Господа, добрый вечер. Пожалуйста, помогите с задачей: Система передачи данных обеспечивает передачу пакетов данных из пункта А в...

Распараллеливание функции захвата пакетов libpcap и обработчика полученных пакетов
Добрый день! Имеется сниффер на базе libpcap, на вход которого может поступать огромное количество UDP пакетов. Задача: поймать каждый...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru