Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  3 670

•  TDictionary Custom Sort  5 800

•  Fast Watermark Sources  5 603

•  3D Designer  8 218

•  Sik Screen Capture  5 913

•  Patch Maker  6 388

•  Айболит (remote control)  6 378

•  ListBox Drag & Drop  5 237

•  Доска для игры Реверси  94 551

•  Графические эффекты  6 570

•  Рисование по маске  5 644

•  Перетаскивание изображений  4 760

•  Canvas Drawing  5 135

•  Рисование Луны  4 863

•  Поворот изображения  4 411

•  Рисование стержней  3 116

•  Paint on Shape  2 360

•  Генератор кроссвордов  3 228

•  Головоломка Paletto  2 551

•  Теорема Монжа об окружностях  3 328

•  Пазл Numbrix  2 200

•  Заборы и коммивояжеры  2 849

•  Игра HIP  1 820

•  Игра Go (Го)  1 740

•  Симулятор лифта  2 072

•  Программа укладки плитки  1 799

•  Генератор лабиринта  2 241

•  Проверка числового ввода  1 925

•  HEX View  2 226

•  Физический маятник  1 911

 
скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

ICQ2000 сделай сам 3




Автор: Alexander Vaga
WEB-сайт: http://icq2000cc.hobi.ru

Разговор по аське:
- Что замолчал?
- Пальцы устали.

Итак, рассмотрим механизм приема FLAP-пакетов. Прием пакетов - это обработчик события onReadData нашего ClientSocket. Задача этого обработчика сводится только к приему FLAP-пакетов и формировании из них связного списка типа FIFO (первым пришел, первым и ушел). Главное корректно отработать границы пакетов.

Каждый пакет принимается в два захода:

  1. сначала принимаем только заголовок FLAP-пакета (всего 6 байт);
  2. затем, узнав из заголовка длину блока данных, принимаем последний (ни байтом больше, ни байтом меньше).

Приняв полный пакет, формируем из него элемент списка FIFO и присоединяем его к списку. Смотрим, как это сделано у меня. Для прима заголовка и блока данных FLAP-пакета объявлены два массива: FLAP и FLAP_DATA соответственно.


procedure TForm1.CLI_ReadData(Sender:TObject; Socket:TCustomWinSocket);
var num,Bytes,fact : integer;
    pFIFO,CurrFIFO : PFLAP_Item;
    buf : array[0..100] of byte;
begin
// узнаем, сколько всего данных уже есть в буфере ClientSocketa
     num := Socket.ReceiveLength;
// в icq_Login мы установили isHdr, т.к. сначала ожидаем заголовок
     if isHDR then begin
// если есть как минимум 6 байт, то читаем 6 байт заголовка в FLAP
       if num>=6 then begin
         Socket.ReceiveBuf(FLAP,6);
// из заголовка узнаем длину блока данных FLAP-пакета
         NeedBytes := swap(FLAP.Len);
// сбрасываем в начало индекс массива FLAP_DATA
         index := 0;
// сбпасываем, чтобы следующее чтение было в FLAP_DATA
// и выходим из обработчика
       isHDR := false;
       end else begin
             // вообще-то ситуация, когда в Sockete меньше 6-и байт
             // пока никак не контролируется (возникает очень редко :)
             // отмечаю этот факт только в окне отладки 
             M(Memo,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
             Socket.ReceiveBuf(buf,num);
             M(Memo,Dim2Hex(@(buf),num));
             M(Memo,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
           end;

// if not isHDR then чтение в FLAP_DATA
end else begin  
// сколько байт читать уже известно: NeedBytes
         Bytes := NeedBytes;
// читаем их в FLAP_DATA[Index]
         fact := Socket.ReceiveBuf(FLAP_DATA[index],Bytes);
// если в Sockete было данных меньше чем нужно, 
// педвинем Index и NeedBytes для следующего входа в обработчик
         inc(index,fact);
         dec(NeedBytes,fact);
         if NeedBytes = 0 then begin
// если весь блок данных FLAP-пакета уже в FLAP_DATA,
// тогда выделаем память для элемента списка FIFO (PFLAP_Item) 
           New(pFIFO);
// копируем заголовок
           pFIFO^.FLAP := FLAP;
           pFIFO^.Next := nil;
// выделяем память для блока данных и копируем его
           GetMem(pFIFO^.DATA,index);
           move(FLAP_DATA,PFIFO^.Data^,swap(FLAP.Len));
           
// добавляем указатель на PFLAP_Item в список
           CurrFIFO:=HeadFIFO;
           if HeadFIFO<>nil then begin
             while CurrFIFO<>nil do
               if CurrFIFO^.Next=nil then begin
                 CurrFIFO^.Next:=pFIFO;
                 break;
               end else CurrFIFO:=CurrFIFO^.Next;
           end else HeadFIFO:=pFIFO; 
// устанавливаем isHDR (в true) уже для прима заголовка
// последующих FLAP-пакетов 
           isHDR := true; 
         end;
     end;
end;

Дальнейшая обработка списка FIFO - это задача уже другой процедуры.





Похожие по теме исходники

Сообщения между процессами Windows




Copyright © 2004-2025 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте