Добрый день! Никто не спорит, что при разработке таких штук, как Герои Меча и Магии или крестики-нолики (с сетью) логичнее использовать протокол TCP.
Конечно, есть люди, которые запилят и это на UDP, докрутят свою проверку получения и т.п., но в данном случае это нелогично.
У меня возник вопрос, можно ли использовать TCP для чего-то более тяжелого, например, сетевых стрелялок или гонок?
И вот почему... Весь минус (а я вижу только один) TCP вытекает из его плюсов - он медленнее UDP. Но сегодня скорость интернета у конечного пользователя в 100-300 раз быстрее, чем 10-15 лет назад, сегодня даже не в столицах есть 40-70 мегабит за 300-400 рублей (5-6$).
Предположим, я собираюсь 15 раз в секунду передавать строку в 50-100 байт с информацией об игроке... Неужели при использовании TCP эти несчастные 200 байт (с учетом служебной информации протокола) будут идти дольше 70 мс. (даже с учетом подтверждения) по каналу в 5 мегабайт/с?
Ramm, здесь в первую очередь пинг важен.
ТСР потоковый.
Простой пример:
Представь что ты отправляеш последовательно 15 пакетов о положении 15 игроков. И пакет #3 из-за лага вдруг потерялся.
TCP: получит 2 первых пакета и будет ждать персылки пакета #3.
UDP: получит все пакеты кроме пакета #3 и будет ждать его пересылки.
Джек Аллигатор
Вопрос, если пинг с сервером (который я узнаю с помощью команды ping "ip"), например 60 мс., то TCP позволит передать за это время только 1 сообщение максимум? Или гарантированно его передаст?
return [](){};
Во-первых, статье скоро стукнет 10 (!!!) лет. 10 лет назад многое что писали...
Во-вторых, там немного странный подход к передаче данных. Зачем передавать данные каждый кадр? Пользователь нажал кнопку вправо, значит он сместится на один шаг вправо, зачем мне передавать его смещение 100 раз в секунду? Достаточно просто отправить данные, что он начал смещение вправо.
Понятное дело, что будут приходить и отстающие ненужные потоки, но это будет компенсироваться тем, что в этот же кратчайший промежуток времени придут и актуальные данные.
UDP не решает другой проблемы - если я отправлю 3 строки по 100 байт, может так случиться, что вытащить полную информацию корректно не удастся ни из одной.
Вот и получается, что я буду отправлять мусор. Или городить ответы-подтверждения, которые тоже не факт, что дойдут.
Мне надо передать всего по 100 байт каждые 70 мс, передать гарантированно, это всего 1.5 кб\с. Ну хорошо предположим, игроков 32, каждый отправляет 100 байт и получает 3100 байт в ответ, 15 раз в секунду, это 48кб\с, ну +служебная информация + потери... Хорошо, умножим на 3, итого 144кб\с.
И что, TCP по определению не в состоянии отправить 100 байт 15 раз в секунду?
RadianTOR
> TCP: получит 2 первых пакета и будет ждать персылки пакета #3.
Получит его и все. Т.е. все будет сделано без моего ведома. Я отправляю координаты x,y,z, а так же вектор его движения x1,y1,z1; они доходят, сервер их получает и перенаправляет остальным игрокам. Игрок N:x,y,z,x1,y1,z1.
RadianTOR
> UDP: получит все пакеты кроме пакета #3 и будет ждать его пересылки.
В итоге с сокета я сниму кучку байтов, попытаюсь понять, что за числа, и будет не хватать, например, координаты z. Или при потере не последнего пакета - координаты y. Остается тупо пропускать и ждать, что следующая строка с клиента придет без потерь и я наконец-то смогу ее понять и переслать остальным, в надежде, что она тоже дойдет.
RadianTOR
А, понял, невнимательно прочитал...
Вся прелесть TCP, насколько я понимаю, повторно отправляются только потерявшиеся пакеты. Он не будет каждый раз пересылать цельный массив а потом сверяться с контрольной суммой, и если не совпадет - запрашивать снова.
Другая ситуация, 31 игрок, 3100 байт, я передаю их клиенту, 10% потеряется, что делать в этом случае? Есть риск вообще ничего не понять.
Ramm
TCP - это поток. Всё приходит ровно так, как ты и отправил. UDP - это пакеты. Тебе никто не мешает засунуть координаты игрока (x, y и z), а так же направление движения в один пакет. Пакеты если и приходят, то всегда целостные (ничего там по байтам не перемещается). А ты видимо хочешь каждую координату в отдельный пакет засунуть, тогда у тебя не только что-то может не прийти, так ещё и не в той последовательности пакеты могут прийти, и я даже слышал что пакеты могут дублироваться.
websoсket используют только tcp, тоесть все игры под веб кидают по tcp, кроме сделанных на flash там я не в курсе, в своем проекте я раздаю пакеты каждые 100мс в бинарном виде, видел проекты которые кидали json, а некоторые и того хуже, так что не парься и используй TCP, единственное проблема это то что если один пакет задержится то все пакеты замирают пока повторно тот не придет, в тестах ( а я много тестил) это не бывают ни у кого - нужно очень постараться чтобы такая проблема была на современных сетях, может на мобилках если он движется, но там и udp не поможет просто связь оборвется. Зато плюсов в разы больше, и нужны ли тебе те проблемы и самописные велосипеды, подумай иной раз, тут советы много кто давать любит но на практике те еще рукожопы, так что бери на чем проще всего делать.
Татарин
> webscoket используют только tcp, тоесть все игры под веб кидают по tcp, кроме сделанных на flash там я не в курсе
Во Flash тоже было только TCP (по крайней мере когда я его использовал). В то время UDP можно было использовать только в AIR.
Татарин
Такие сообщения вдохновляют=)
s3dworld
> Тебе никто не мешает засунуть координаты игрока (x, y и z), а так же
> направление движения в один пакет.
Ого, я просто с TCP работал, и о размерах пакетов не думал, вообще о пакетах не думал - сокеты на TCP все за меня делали... А тут с UDP куча проблем. Как можно установить размер пакета (где об этом почитать, особенно на C# интересно, конкретно - про размер пакетов)
Ramm
Один send() будет равняться одному пакету.
В 2017 логичнее использовать https://ru.wikipedia.org/wiki/SCTP ,... который потоковый и с гарантией доставки, как TCP, но позволяет разбивать данные на сообщения, как UDP. Засада в том, что Microsoft так и не добавила SCTP стек в Windows.
s3dworld
Быть такого не может... Это с использованием класса Socket? В С#? Получается, размер пакета 1) не определен, может быть разным 2) не ограничен??? Где можно увидеть подтверждения?
0iStalker
Да, и информации по практическому использованию мало
Для части данных не нужна гарантия доставки, для обновления координат объектов, к примеру. Вместо повторной пересылки можно новые координаты послать, они компенсируют пропажу. Но tcp не позволяет реализовать такую линию поведения, он будет пересылать пропавшие данные раз за разом, пока не добьется успеха, за это время накопится еще куча не отосланного, система запросто может начать не справляться с нагрузкой, лаг будет расти и расти, пока не достигнет примерно 30 секунд, после чего соединение рвется.
Ramm
> Быть такого не может...
Чего быть не может?! Тебе нужно отправить данные? Забиваешь ими какой-то буфер и отправляешь его через send(). Далее произойдёт следующее:
Тема в архиве.