Получение данных с помощью Winsock - PullRequest
1 голос
/ 24 марта 2010

Сейчас я программирую сетевое взаимодействие для своей онлайн-игры, и я не совсем уверен, что делать с получением данных. Проблема в том, что я не могу точно угадать размер пакета, поэтому я подумал о том, чтобы прочитать всего 4 байта из пакета и преобразовать их в целое число, чтобы узнать размер пакета. Тогда я просто создаю буфер такого размера и получаю остальную часть пакета, это хорошая идея?

Для вашей информации, я использую неблокирующий ввод / вывод.

Ответы [ 3 ]

1 голос
/ 24 марта 2010

Ваш подход звучит разумно - вы, по сути, включили бы размер сообщения в заголовок сообщения, что, вероятно, является наиболее надежным способом справиться с этим в вашей ситуации. В качестве альтернативы вы можете использовать пакеты фиксированной длины (ick) или использовать какой-либо символ разделителя (который НЕ будет работать вообще для двоичных сообщений).

Эта ссылка основы протокола сокета содержит дополнительную информацию, которая может помочь.

0 голосов
/ 24 марта 2010

Если вы не осторожны, то, что вы предлагаете, - это дыра в безопасности. Так что будьте очень осторожны - особенно когда доверяете сетевому вводу.

Вы не указали TCP или UDP, поэтому я просто дам вам общее руководство.

Для TCP или UDP, просто выделите один буфер размером N, где N - самый большой размер сообщения, которое вы, возможно, отправили с удаленного проигрывателя или сервера. Для UDP, я бы порекомендовал хранить это менее 1500 байт. Для TCP вы можете иметь большие размеры.

Для вашего сокета, будь то UDP или TCP, сделайте его неблокирующим. Это делается для того, чтобы вы не зависали игровой цикл во время ожидания данных.

Добавить размер и crc-хэш в заголовок любого сообщения. Когда вы получаете сообщение в виде пакета UDP, если размер заголовка пакета больше, чем N (что означает, что вы уже получили усеченный пакет) или хэш не соответствует тому, что вы вычисляете для размера приема, просто отклоните пакет. Я вызываю это потому, что без дополнительных проверок целостности хакеры и мошенники будут использовать вашу структуру пакетов для победы.

Для TCP вы по сути создаете свои сообщения так, как вы их описываете. Каждое сообщение имеет заголовок, определяющий количество байтов, которые должны следовать. Но сделайте то же самое, что и для UDP, добавьте свой собственный заголовок для проверки целостности. Закройте сокет, если вы когда-либо получили сообщение об ошибке и ASSERT.

В TCP из-за сегментации TCP вы можете не получить все сообщение в одном вызове recv. То есть, если вы получили только частичное сообщение, сохраните его во временном буфере. При последующем вызове recv (в следующем игровом кадре) добавьте этот буфер. Вам придется хранить переменные для отслеживания ожидаемого конца сообщения, чтобы случайно не прочитать следующее сообщение, которое могло быть отправлено.

Удачи.

0 голосов
/ 24 марта 2010

Если вы используете TCP-сокеты, НИКОГДА не полагайтесь на размер пакета. Поток данных - это поток байтов, а не поток пакетов.

...