Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > PureBasic

PureBasic Мощный кросс-платформенный язык среднего уровня на основе BASIC. Подходит для решения широкого круга задач.

Ответ
 
Опции темы
Старый 18.07.2012, 21:55   #1
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Вопрос Непонятки с TCP/IP

Сервер на пурике принимает "пакет". В нем сначала идет 4-байтовый integer, в котором содержится полная длина последующего сообщения. Проблема в том, что очень редко и в рандомных случаях этот integer теряется, сразу идет сообщение. В таком случае сообщение обрабатывается, но следующий пакет, если он уже пришел, может быть утерян, так как неизвестно где данный заканчивается.
Может кто сталкивался? Очень неприятная проблема...
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 22:21   #2
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Непонятки с TCP/IP

Читаешь всегда ТОЧНО столько сколько ожидаешь?
При этом проверяй что прочтённая длина равна ожидаемой. Если меньше чем ожидал, значит жди ещё пока остаток данных не прийдёт, это редкость, т.к. обычно данные приходят обычно слитые, нежели разбитые (но и такое бывает).
Так что читая 4 байта (заголовок), далее читай данные длины, и убедись что прочитал ровно столько, сколько ожидал, лишь потом освобождай блок для последующего чтения.

Тут больше логическая проблема кода.
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 22:29   #3
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Непонятки с TCP/IP

Да я вообще не в понятках в чем проблема. Читаю ровно столько сколько отправляю - проверял в логах. Потеря заголовка проявляется очень редко и рандомно. Даже подряд когда отправляю 100 разных пакетов (без задержки между ними), проблема не вылезает, ну если только очень редко, - значит проблема не в логике. хз даже что делать то...((
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 22:41   #4
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Непонятки с TCP/IP

Ты уверен что прочтённые данные длиной которой ожидаешь, и ты принял все что ожидал? При приёме, есть переменная с длиной.
Также, ты блокируешь чтение между началом чтения хедера и тела до полного прочтения тела?
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 22:55   #5
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Непонятки с TCP/IP

Вот код:
ReceiveNetworkData(TCPclientID,*TCPBuffer,4)
TCPlength.i=PeekL(*TCPBuffer)
If TCPlength>1000:TCPlength=1000:PrintN("Packet error!"):EndIf
ReceiveNetworkData(TCPclientID,*TCPBuffer,TCPlength)
TCPPacket=PeekS(*TCPBuffer,TCPlength)
Сколько тестил - он всегда(!) читает сообщение необходимой длины, не больше и не меньше. Но очень редко TCPlength захватывает 4 байта самого сообщения. Просто integer куда-то пропадает...

В этом коде еще нет проверки на то, если сообщение пришло не полностью, но когда на одном компьютере тестишь - это проблем не вызывает, проверял.
__________________
galaxies.su | dstalk.ru

Последний раз редактировалось DStalk, 20.07.2012 в 15:25.
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 22:58   #6
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Непонятки с TCP/IP

Ты запускаешь данную функцию по ассинхронному каллбеку, или один раз в цикле опрашиваешь?
Ты проверил что данные хедера все пришли (4 байта)?
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:00   #7
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Непонятки с TCP/IP

в цикле, проверка не нужна (в сообщение выше дописал)
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:03   #8
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Непонятки с TCP/IP

У меня сомнения по этому коду:
If TCPlength>1000:TCPlength=1000:PrintN("Packet error!"):EndIf
Ты проверяешь если длина больше 1000, значит ошибка (типо число в заголовке никогда не больше 1000), но затем продолжаешь читать.
Ты уверен что проблем нету с подсчётом длины пакета?
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:08   #9
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Непонятки с TCP/IP

Уверен. А вот эта строчка выдает ошибку, но принудительно читает пакет, вместе с возможными кусками последующих пакетов. Этой строчки вообще не будет, если проблема перестанет проявлятся.
А выдает TCPlength.i=PeekL(*TCPBuffer) больше тысячи, потому что в памяти находится первые четыре байта пакета, а там символы, если считать их из памяти как integer, всегда получается больше 1000. Это типа проверка на ошибку пакета...

Да, и по идее, у нормальных пакетов длина всегда меньше 1000.

Забыл сказать - пакеты отправляю прогой на Blitz3D, пробовал двумя способами:
;1 способ
WriteString streamIP,msg1$
;2 способ
WriteInt streamIP,Len(msg1$)+2
WriteLine streamIP,msg1$
Оба способа дают одинаковые результаты...
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:16   #10
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Непонятки с TCP/IP

Ну почему число TCPlength в итоге больше 1000 это и так понятно.

Тут нету проверки сколько данных ты принял, это и вызывает проблему скорее всего. Т.к. в очень редких случаях ты примешь не достаточно данных (в сетевом стёке не всё ещё), а ожидаешь достаточно.
Попробуй проверку замутить:
ReceiveNetworkData(TCPclientID,*TCPBuffer,TCPlength)
MessageLength.i=PeekL(*TCPBuffer)
If MessageLength != TCPlength : PrintN("Not the same!") : EndIf
Также снова, убедись что подсчёт длины пакета корректный и сливаешь ты их тоже корректно.
Лучше запости код где ты это делаешь, и опиши, делаешь ассинхронно или синхронно?
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:20   #11
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Непонятки с TCP/IP

Проверял я это все. Если бы принял недостаточно данных - то следующий PeekL(*TCPBuffer) выдал бы данные с середины предыдущего пакета - такого ни разу не было. Он всегда выдает или правильную длину пакета, или, очень редко, 4 байта начала тела сообщения.

В сообщении выше дописал про отправку пакетов))
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:25   #12
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Непонятки с TCP/IP

Длина текста будет не соответствовать длине пакета.
Хз как блиц, но в более низкого уровня, нужно сперва чётко конвертировать строки в бинарное представление и вычислять длину бинарного массива. Т.к. тот же символ в UTF8 или ASCII уже разных размеров.
Также WriteLine будет писать дополнительные данные конца строки.

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

Короче, в пурике всё ок, это блиц тупит.
Если есть возможность конвертировать в блице строку в бинарный вид и отправлять массив байтов - делай лучше так.
Если есть возможность использовать тот же RakNet - лучше юзай его.
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:28   #13
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Непонятки с TCP/IP

Все то что ты написал, и про кодировки и про дополнительные символы я учел. Смысл в том что проблема специфическая очень - пропадают именно 4 байта длинны сообщения, все остальное в порядке, и всегда нормально читается.

Есть вариант решения, тупой правда) Отправлять перед телом сообщения не один а два одинавковых integer`a. Даже если один пропадет, второй нормально прочитается, и пакеты после данного не будут потеряны
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Старый 18.07.2012, 23:30   #14
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,861 пользователей)
Ответ: Непонятки с TCP/IP

Теперь я скорее всего догадался в чём проблема:
Блиц возможно применяет собственный алгоритм склеивания сообщений, тем самым если слишком часто отсылать, может клеить стринги вместе.
Костыль который предлагаешь - супер изврат..

Короче говоря, лучше возьми либку.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
DStalk (18.07.2012)
Старый 18.07.2012, 23:39   #15
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Непонятки с TCP/IP

Насчет склеивания сообщений - вторым методом отправляю integer отдельно, и все равно такая фигня. Кстати тестил и на удаленных соединениях с несколькими клиентами. Точно та же проблема.

Странно все это, ну да ладно А костыль изврат, ага, но зато не будет проблемы, и нагрузка от него на сервер и соединение очень незначительные.

MoKa, отдельное спасибо за интерес и инфу))
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 06:29.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com