Вернуться   CoderX :: Forums > Lineage II > L2PacketHack > Разработка
Войти через OpenID

Разработка Раздел для совместной разработки/доработки программы

Чат (Новых сообщений с момента вашего последнего визита нет)
Загрузка...
Задавайте ваши вопросы на форуме. Чат предназначен для небольших разговоров.
 
Ответ
 
Опции темы Опции просмотра
Старый 29.02.2012, 15:17   #1
Пользователь
 
Регистрация: 17.12.2010
Сообщений: 37
Сказал Спасибо: 13
Имеет 1 спасибку в 1 сообщении
glukmaker пока неопределено
По умолчанию

Цитата:
Сообщение от Aries Посмотреть сообщение
И да, сразу совет. Не считывайте все данные из сокета, как те только туда пришли, т.к. может быть ситуация, что пришла только часть пакета.
Правда гуру почему-то советуют все же считывать все данные с сокета в буфер и уже в буфере разбирать их по пакетам...

Вот, когда-то интересовался подобным вопросом.
http://delphimaster.ru/cgi-bin/forum...1319485327&n=4

пришлось вместо первоначального варианта:
Код:
type TPacket: packed record
 case boolean of
 true: (buf: array[0..8191] of byte;);
 false: (len:word;
         typepack:byte;);
 end;

var
 Packet:TPacket;

...
begin
 while true do
   begin
     if recv(FSocket,Packet,2,MSG_PEEK)<2 then Exit;
     if recv(FSocket,Packet,Packet.len,MSG_PEEK)<packet.len then Exit;
     recv(FSocket,Packet,Packet.len,0);
     Obrabotka(Packet); // функция обработки пакета
   end;
end;
переписать приблизительно так (ну это мой вариант на тот момент, сейчас он уже еще доработан, но исходники не при мне):

Код:
...
private
   FBuffer: packed array[0..8191] of byte;
   FStartBuffer:integer;
   FEndBuffer:integer;
...

procedure TMyClass.ReceivePackets;
var
 s:Integer;
begin
 s:=recv(FSocket,FBuffer[FEndBuffer],length(FBuffer)-FEndBuffer,0);

// тут нужно обработать возможные ошибки.

 inc(FEndBuffer,s);
 while true do
   begin
     if FEndBuffer-FStartBuffer<2 then Break;
     move(FBuffer[FStartBuffer],Fpacket,2);
     if FPacket.len>sizeof(FPacket) then
       begin
         // Тут нужно закрыть сокет, и сгенерировать исключение
         // так как прием таких пакетов не планируется
         Exit;
       end;
     if FEndBuffer-FStartBuffer<Fpacket.len then Break;
     move(FBuffer[FStartBuffer],FPacket,Fpacket.len);
     inc(FstartBuffer,Fpacket.len);  // увеличиваем значение стартовой позиции буфера на величину забранных данных
     if FGame then ProcessingGame else ProcessingAuth;  // обработка выделенного пакета
    end;

  // Оптимизация буфера (чтобы обойтись без постоянных сдвигов буфера
  // сдвигать будем только при крайней необходимости)

  // Если буфер пустой, устанавливаем позиции начала и конца на 0
  if FStartBuffer>=FEndBuffer then
  begin
    FStartBuffer:=0;
    FEndBuffer:=0;
  end;
  // Оцениваем длину свободного хвоста буфера, если он менее 2 кб, то сдвигаем данные к началу буфера
  if length(FBuffer)-FEndBuffer<2048 then
  begin
    move(FBuffer[FStartBuffer],FBuffer[0], FEndBuffer-FStartBuffer);
    FEndBuffer:=FEndBuffer-FStartBuffer;
    FStartBuffer:=0;
  end;
end;

Последний раз редактировалось glukmaker, 29.02.2012 в 15:24.
glukmaker вне форума   Ответить с цитированием
Старый 29.02.2012, 15:45   #2
Местный
 
Аватар для Aries
 
Регистрация: 19.01.2011
Сообщений: 241
Сказал Спасибо: 7
Имеет 26 спасибок в 22 сообщенях
Aries пока неопределено
По умолчанию

Цитата:
Сообщение от glukmaker Посмотреть сообщение
Правда гуру почему-то советуют все же считывать все данные с сокета в буфер и уже в буфере разбирать их по пакетам...
ну собственная буферизация имеет смысл только в том случае если обработка данных слишком долгая, и возможно переполнение буфера сокета.
Aries вне форума   Ответить с цитированием
Старый 02.03.2012, 14:18   #3
Местный
 
Аватар для Sherman
 
Регистрация: 24.04.2008
Сообщений: 364
Сказал Спасибо: 15
Имеет 116 спасибок в 83 сообщенях
Sherman пока неопределено
По умолчанию

Цитата:
Сообщение от Aries Посмотреть сообщение
ну собственная буферизация имеет смысл только в том случае если обработка данных слишком долгая, и возможно переполнение буфера сокета.
Несогласен, т.к. своя буферизация еще и избавляет от проблем связанных с приемом данных из разных фреймов. Если пришел не полный пакет, отпадает необходимость ожидания дочитывания остатка, а такое по моему опыту бывает часто, когда прилетает нецелое количество пакетов. Можно спокойно отпустить сокет для приема дальше, и заняться обработкой имеющихся полных пакетов. Ассинхронное использование сокета короче.

Последний раз редактировалось Sherman, 02.03.2012 в 14:28.
Sherman вне форума   Ответить с цитированием
Ответ

  CoderX :: Forums > Lineage II > L2PacketHack > Разработка



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

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


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

vBulletin style designed by MSC Team.
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Locations of visitors to this page
Rambler's Top100

Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!