Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / TCP vs UDP в 2017 году (2 стр)

TCP vs UDP в 2017 году (2 стр)

Поделиться

Страницы: 1 2 3 4 Следующая

romgermanПостоялецwww9 окт. 201714:50#15
Ramm
> Получается,  размер пакета 1) не определен, может быть разным 2) не
> ограничен??? Где можно увидеть подтверждения?
Прочти уже пару статей с gafferongames. Даже если некоторые статьи достаточно старые, это не значит, что за это время прям что-то глобально изменилось. Ровным счетом ничего не изменилось, всё те же технологии, всё те же приёмы. И в одной из статей написано как выбирать размер пакета.
ZabПостоялецwww9 окт. 201715:44#16
s3dworld
> Данные придут (внутри них ничего не будет перемешано)
> Данные не придут
> Данные придут несколько раз

- Пакеты могут придти не в той последовательности, что посылались, обгоняя друг друга в пути.
- В твой поток пакетов могут вклиниться посторонние. Если они просто посторонние, не от злоумышленников, чужие можно отфильтровать по адресу, но адрес в пакете можно и подделать.

ZabПостоялецwww9 окт. 201715:50#17
Ramm
> 1) не определен, может быть разным 2) не ограничен???
Размер очень даже определен для конкретного пакета. Он может быть разным. Сколько отошлешь - столько и придет. Каждый пакет имеет свою длину.
Размер ограничен. В разных сетях разные ограничения, но примерно на 1.2Кб можешь рассчитывать. В локальных сетях благополучно ходят пакеты и по 64Кб. Максимальный размер пакета можно узнать через API.
kiparПостоялецwww9 окт. 201717:22#18
у больших пакетов UDP есть проблема. Если датаграмма разбивается и одна часть теряется, то пересылаются (ну или теряются) все части. Получается что при потере пакетов будет еще хуже чем с TCP, там хотя бы только потерянное пересылается.


А так - хочешь пинг получше но заморочиться побольше, то UDP, если хочешь заморочиться поменьше но пинг похуже то TCP, если вообще не хочешь заморачиваться то готовую библиотеку.

Правка: 9 окт. 2017 17:23

ChupakaberПостоялецwww9 окт. 201717:25#19
Zab
> Максимальный размер пакета можно узнать через API.
реально максимальный размер пакета можно узнать только прокинув несколько пакетов и проверив - прошло или нет
кто знает какая там маршрутизация по пути, сам же сказал, что в некоторых локальных сетях благополучно много пролазит

т.е. можно прокинуть (пингануть) например 1400 байт и если прошли 1400 - попробовать 2800, если не прошли то 2100 и так уполовинивать пока точное количество байт не увидим пришедшими, за 10-12 итераций можно точное значение найти

прикинуть ориентировочно на что рассчитывать можно почитав про термин MTU, это параметр который настраивается на маршрутизаторах

и я бы рекомендовал взять размер пакета за основу исходя из минимально возможного MTU в сетях, ну т.е. 576 байт (до вычета заголовков), или ориентироваться на среднестатистические 1400-1490 и надеяться на лучшее

geletkaПостоялецwww9 окт. 201721:57#20
Если что, скорость интернета тут не шибко важна и с гигабитным интернетом лагать может сильно, почти все зависит от сервера, как будут обрабатываться данные, сколько игроков обслуживает, во сколько потоков, как синхронизируются клиенты.
Если сервер начнет "уставать", он будет выкидывать пакеты и блокировать адреса, если нет, то просто ляжет.
Притом интересно бывает, 1500 клиентов сервяр грузят на 10%, а потом к примеру 2000 клиентов уже кладут сервер. Все зависит от обработки данных. Ну, конечно можно думать про целую сеть серверов))
Но для простой гоночки хватит и TCP с JSONом, в социгрушках до сих пор так делают, можно же не хило обманывать игроков...
МизраэльПостоялецwww9 окт. 201722:44#21
Ramm
> У меня возник вопрос, можно ли использовать TCP для чего-то более тяжелого,
> например, сетевых стрелялок или гонок?
Если тебе нужен простой ответ, то нет, нельзя. Не важно, что раньше у тебя была скорость 10Мб/с, а теперь 100Мб/с, важно как изменилась латентность. А она почти не поменялась, более того есть физическое ограничение в виде скорости света. Так что с десятилетней давности особых изменений нет.

Ramm
> В итоге с сокета я сниму кучку байтов, попытаюсь понять, что за числа, и будет
> не хватать, например, координаты z. Или при потере не последнего пакета -
> координаты y. Остается тупо пропускать и ждать, что следующая строка с клиента
> придет без потерь и я наконец-то смогу ее понять и переслать остальным, в
> надежде, что она тоже дойдет.
В таких играх по сети обычно передаётся состояние объекта игрока одним пакетом (положение, ориентация, скорость линейная и угловая и ещё пара статсов). Если пакет не дошёл до сервера, то это нормально, будет выслан повторный пакет (примерно 25 раз в секунду) с новыми данными. С TCP так не выйдет.

Вот пара отличных статей:
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
https://developer.valvesoftware.com/wiki/Latency_Compensating_Met… _Optimization

С тех времён ничего особо не поменялось.

МизраэльПостоялецwww9 окт. 201723:04#22
Ramm
и ещё к слову, не стоит работать с сокетами напрямую. Лучше взять какое-то готовое сетевое API по типу RakNet. С графикой же никто в своём уме напрямую не работает, странно, что с сетью до сих пор вручную байтики пересылаем. Раньше был DirectPlay, жаль что прекратили развивать, отличная штука была.
mmgПостоялецwww9 окт. 201723:04#23
Полумертвый "Сурвариум" - отличный предмет для данного обсуждения. Сколько усилий вложено в систему синхронизации с сервером - но провайдеры непробедимы.
Тема по багам синхронизации.
ZabПостоялецwww10 окт. 20170:58#24
Мизраэль
К сожалению, "готовое сетевое API" не избавляет от необходимости знать все на нижнем уровне. Нет достаточно качественных библиотек. Получается что кроме заморочек сокетов, ты вынужден будешь разбираться еще и заморочками использованной библиотеки, той же raknet, к примеру. С библиотеками сложнее работать, чем без них.

DirectPlay то ты сам использовать пробовал? Ну и чем же он "отличен"? Его не зря убрали, он создавал массу неразрешимых проблем. В основном на этапе сопровождения, конечно. Ты вынужден был администрировать комп каждого игрока, для игрока самостоятельная настройка DirectPlay была обычно не по силам, а без настроек DirectPlay может лишь тривиальные вещи, которые на сокетах выполняются проще и естественнее.

RammПостоялецwww10 окт. 20177:30#25
Спасибо, все более-менее проясняется, UDP теперь не кажется таким страшным.
Мне для моих нужд хватит и 506 байтовых пакетов. Они никем, я так понял, дробиться не будут.

Zab
> В твой поток пакетов могут вклиниться посторонние. Если они просто
> посторонние, не от злоумышленников, чужие можно отфильтровать по адресу, но
> адрес в пакете можно и подделать.
Более того, если злоумышленник и клиент за одним NAT-ом, то и адрес подделывать не придется.

А как узнать где закончился один пакет и начался другой? Предположим, на один UDP-сокет пришло 2 пакета, один - 100 байт, другой 130 байт.
Считываю их так (С#):

            string builder = "";
            int bytes = 0; // количество полученных байтов
            byte[] data = new byte[256]; // буфер для получаемых данных

            //узнаем адрес, с которого пришли данные
            EndPoint remoteIp = new IPEndPoint(IPAddress.Any, 0);
            //проверяем, не пришло ли чего на сокет
            if (UDP1.Available > 0)
            {
                while (UDP1.Available > 0)
                {
                    bytes = UDP1.ReceiveFrom(data, ref remoteIp);
                    builder += Encoding.ASCII.GetString(data, 0, bytes);
                    if (builder.Length>=100)
                    {
                        break;
                    }
                }
      }
Черпаю данные буфером в 256 байт, при этом пытаясь узнать адрес отправителя, но я не знаю поведения функции ReceiveFrom, если в одном буфере окажутся два пакета от двух разных отправителей...
Как понять, где закончился один пакет и начался другой?

HacKeR13Постоялецwww10 окт. 201710:38#26
Ramm
> Как понять, где закончился один пакет и начался другой?
Такая беда и с TCP случается.
Я в таком случае использовал свое определение окончания пакета.
Т.е. в конец пакета всовывал какую-то строку, и при получении проверял на индекс этой самой строки. Если она не в конце - пришло несколько пакетов.
Также может быть такая ситуация что тебе придет пакет не полностью
RammПостоялецwww10 окт. 201711:08#27
HacKeR13
На той странице человек расписал, что пакет не может придти не полностью.
s3dworld
> Данные придут (внутри них ничего не будет перемешано)
> Данные не придут
> Данные придут несколько раз
Да, большие пакеты (от 1000 байт, в зависимости от MTU) могут быть разбиты, но небольшие (до 576 - 60 - 8 = 508 байт) придут полностью, либо не придут вообще.
HacKeR13
> Такая беда и с TCP случается.
Там единый поток, мне не надо ничего знать о пакетах, я с ними вообще никак не контактирую, поэтому конца одного пакета и начала другого там нет, установили соединение -> шлем данные туда-обратно -> обрабатываем их.
Тут малого того, что пакеты теряются и дублируются, так я еще не могу извлечь его целиком, при том что в его заголовке есть контрольная сумма и информация о размере.
Это раз.
Да еще любой может мне своих пакетов накидать, в т.ч. разных размеров.
Это два.
Т.Е. Я ТОЧНО НЕ МОГУ СЧИТАТЬ ПАКЕТ ЦЕЛИКОМ? БЕЗ ЗАХВАТА КУСКА СЛЕДУЮЩЕГО ПАКЕТА?
HolyDelПостоялецwww10 окт. 201711:24#28
Ramm
> могут быть разбиты
если MTU бьет датаграмму на части, это не значит, что в твою программу она прийдет по частям. Операционная система (или сетевая карта?) соберут из частей, проверят контрольную сумму и отдадут ее приложению.

как уже писали в 14м посте, датаграмма может:
1) прийти целиком
2) не прийти совсем
3) прийти несколько раз.

Битой, или не полной, она не дойдет.

Правка: 10 окт. 2017 11:25

RammПостоялецwww10 окт. 201711:29#29
HolyDel
Т.е. вот это:
HacKeR13
> Также может быть такая ситуация что тебе придет пакет не полностью
неправда?
А конец пакета самому искать?

Страницы: 1 2 3 4 Следующая

/ Форум / Программирование игр / Сеть

2001—2017 © GameDev.ru — Разработка игр