supernewbie, нет, дело совсем не в этом, ибо 1) я же дошел уже до EnterWorld. 2) Я написал, что анализирую пакеты сразу после того как их получаю и там уже сразу они слишком большие.
xkor, вот WMSOCK_RS_EVENT, в котором я принимаю пакеты (прошу не обращать внимания на всякие тупости, связанные с RecvPktCount и numpck, ибо это лишь тестовая версия ):
Код:
procedure TForm1.WMSOCK_RS_EVENT(var Msg: TMessage);
var
SockError: integer;
Len:integer;
s : string;
begin
//проверка на ошибки
SockError:=WSAGetSelectError(Msg.lParam);
if (SockError<>0) then begin
if SockError=10053 then RichEdit1.Lines.Add('RS was Disconnected')
else RichEdit1.Lines.Add('RS error: '+inttostr(SockError));
CloseSock(RS_sock);
Exit;
end;
//если нет ошибок:
case WSAGetSelectEvent(Msg.lParam) of
FD_Read: begin
FillChar(main_buff,Length(main_buff),0);
Len:=recv(RS_Sock,main_buff,MAX_PKT_SIZE,0);
s := IntToStr(numpck) + '.txt';
numpck := numpck + 1;
if numpck > 100 then numpck := 101;
// SaveBuf(s, len);
inc(RecvPktCount);
if RecvPktCount > 13 then RecvPktCount := 14;
if RecvPktCount <= 4
then LS_parser(main_buff,Len)
else GS_parser(main_buff,Len);
end;
FD_Close: begin
RichEdit1.Lines.Add('RS was Disconnected');
CloseSocket(RS_Sock);
end;
end;
end;
Собственно из этого всего главная строка:
Len:=recv(RS_Sock,main_buff,MAX_PKT_SIZE,0);
и вот main_buff (main_buff: array[0..MAX_PKT_SIZE-1] of byte) у меня и заполняется до 11 или 16 кбайт
Вот, кстати, лог пакетов с моей программы (первых 2 после EnterWorld, а точнее 1 и лишь маленький кусок второго).
Пакеты декодированы:
Как видно, в моей проге первый пакет показывает нормально, второй пакет в принципе тоже, а вот третий как-то накладывается на второй, причем в нем уже не найти начало, то ли я вообще хз...
Последний раз редактировалось Kilatif, 15.07.2011 в 23:30.
Kilatif, не вижу в процедуре приема контроля длины пакета. Где ты проверяешь сколько реально байт считано с сокета, совсем не обязательно в буфере приема будет весь пакет? Думаю что проблема начинается при приеме первого большого пакета который нужно считывать с сокета более чем за 1 прием.
Yegor, Ну как бы у меня все пакеты помещаются в мой буфер вполне нормально. Пакеты всегда приходят разной длинны, а не какой-то предположительно максимально фиксированной (т.е. например у меня буфер на 16 кб, а приходит всегда фиксировано 14 кб, т.е. сокет обрезает как-то, нет, такого нет). Ну и если проанализировать даже вот те логи, которые я скинул, то видно, что вроде как после той части, что я выделил жирным цветом (это в l2phx полностью второй пакет) сразу должно быть C8 00 - размер следующего пакета, а там не понятно что....
Kilatif,уверен что первый пакет принят полностью? Дело не в размере буфера а в том что интернет имеет задержки, и пакеты могут доставляться за несколько приемов даже весьма небольшого размера.
1.Не вижу отдельно приема первых 2х байт из буфера чтобы узнать реальную длину пакета.
2.Почему из буфера пытаешься прочитать сразу все содержимое?
Len:=recv(RS_Sock,main_buff,MAX_PKT_SIZE,0);
В буфере может быть сразу несколько пакетов.
В любом случае для безошибочного приема пакета необходимо сначала считывать его длину (первых 2 байта), а затем читать с сокета до той поры пока эта (длина - 2 байта) не будет принята полностью (в твоем случае если пакет принят не полностью то необходимо ожидать следующего евента).
В любом случае для безошибочного приема пакета необходимо сначала считывать его длину (первых 2 байта), а затем читать с сокета до той поры пока эта (длина - 2 байта)
на логин сервере тоже 2 байта длинна идет вначале? или только на гейм?
supernewbie, я не думаю что будет игнорироваться размер следующего пакета, при отправке сразу нескольких, ведь если игнорируется длина следующего пакета, как тогда узнать настоящую длину при таком слиянии? =)
у меня длина пакета в проге никак не выделяется, она просто пишется в логах вместе со всем пакетом в первых двух байтах, ибо я с сокета криво читаю (т.е. читаю все, что мне дает сокет, а не то, что мне нужно), об этом мне уже все пояснил Yegor в своем посте. а что касается того, почему работает, если буфер такой загаженый, ответ прост, я обрабатываю не весь буфер, а лишь длину, которую ему задаю. (т.е. длину, которая указана в первых двух байтах)
Yegor, хорошо... свои ошибки в приеме пакета в сокете я понял. Но или я тебя понял не до конца или ты меня не понял, но... Если ты говоришь, что несколько пакетов может придти за раз, то почему в моем втором принятом пакете после куска правильного (жирным цветом выделено) не начинается 3ий пакет (пусть и в зашифрованном виде)? Ведь это на мой взгляд было бы логично. Т.е. там сразу после выделенного жирным ведь по логике должно идти первых два байта размера третьего пакета, но там этого вовсе нет.
Добавлено через 1 минуту supernewbie, да и на логин тоже первых 2 байта это размер пакета.
Последний раз редактировалось Kilatif, 16.07.2011 в 10:59.
Причина: Добавлено сообщение