Delphi-IOCP研究笔记<七>===接收数据的解码器(Decoder)和数据处理

简介: 今天完成了第三点,初步按照netty 的做法制作了Decoder,由于我现在用的2007还没有泛型,所有我使用的返回TObject做法 我先介绍下netty的处理数据的流程 1.IOCP接收的数据。

今天完成了第三点,初步按照netty 的做法制作了Decoder,由于我现在用的2007还没有泛型,所有我使用的返回TObject做法

我先介绍下netty的处理数据的流程

1.IOCP接收的数据。

2.写入到套接字对应的缓存。

3.调用Decoder,进行解码。

4.如果解码成功调用套接字对应的数据处理方法。

 

第一步和第二步我把他归纳到IOCP的底层通信要完成的功能。

第三步在这里需要和客户端定义协议。和数据打包和拆包的格式。

第四步处理具体的业务逻辑。

 

下面我一一贴出代码

第一步由IOCP完成。

第二步

if PerIoData.IO_TYPE = IO_TYPE_Recv then
begin
            //加入到套接字对应的缓存中,处理逻辑
            lvClientContext.RecvBuffer(PerIoData.DataBuf.buf, PerIoData.Overlapped.InternalHigh);
            TIODataMemPool.instance.giveBackIOData(PerIoData);

 

//加入cs控制,避免多工作线程,写入数据混乱

procedure TClientContext.RecvBuffer(buf: PAnsiChar; len: Cardinal);
var
  lvObject:TObject;
begin
  FCS.Enter;
  try
    //加入到套接字对应的缓存
    FBuffers.AddBuffer(buf, len);

    //调用注册的解码器<进行解码>
    lvObject := TContextFactory.instance.FDecoder.Decode(FBuffers);
    if lvObject <> nil then
    try
      //解码成功,调用业务逻辑的处理方法
      dataReceived(lvObject);
    finally
      lvObject.Free;
    end;
  finally
    FCS.Leave;
  end;
end;

 

//在运行IOCP服务时注册解码器

procedure TfrmMain.btnIOCPAPIRunClick(Sender: TObject);
var
  lvData:PInteger;

  lvdwThreadId:DWORD;
begin
  __ListenPort := StrToInt(edtPort.Text);

  //注册解码器
  TContextFactory.instance.registerDecoder(FDecoder);
    
  CreateThread(nil, 0, @D10_IOCPRun, Pointer(__ListenPort), 0, lvdwThreadId);
end;

 

JSonStream的解码器<可以根据自己的格式进行编写解码器>

function TJSonStreamDecoder.Decode(const inBuf: TBufferLink): TObject;
var
  lvJSonLength, lvStreamLength:Integer;
  lvData:String;
  lvBuffer:array of Char;
  lvBufData:PAnsiChar;
  lvStream:TMemoryStream;
  lvJsonStreamObject:TJSonStreamObject;
begin
  Result := nil;

  //如果缓存中的数据长度不够包头长度,解码失败<json字符串长度,流长度>
  if (inBuf.validCount < SizeOf(Integer) + SizeOf(Integer)) then
  begin
    Exit;
  end;

  //记录读取位置
  inBuf.markReaderIndex;
  inBuf.readBuffer(@lvJSonLength, SizeOf(Integer));
  inBuf.readBuffer(@lvStreamLength, SizeOf(Integer));

  //如果缓存中的数据不够json的长度和流长度<说明数据还没有收取完毕>解码失败
  if inBuf.validCount < (lvJSonLength + lvStreamLength) then
  begin
    //返回buf的读取位置
    inBuf.restoreReaderIndex;
    exit;
  end;


  //解码成功
  lvJsonStreamObject := TJSonStreamObject.Create;
  Result := lvJsonStreamObject;

  //读取json字符串
  if lvJSonLength > 0 then
  begin
    SetLength(lvData, lvJSonLength);
    ZeroMemory(@lvData[1], lvJSonLength);
    inBuf.readBuffer(@lvData[1], lvJSonLength);
    lvJsonStreamObject.JSon := SO(lvData);
  end;


  //读取流数据 
  if lvStreamLength > 0 then
  begin
    lvStream := TMemoryStream.Create;
    lvStream.Size := lvStreamLength;
    inBuf.readBuffer(lvStream.Memory, lvStreamLength);
    lvJsonStreamObject.setStream(lvStream);
  end;

end;

 

//业务逻辑处理

//这里我简单的做了一个客户端发送文件的列子。

procedure TClientContext.dataReceived(const pvDataObject:TObject);
var
  lvJsonStream:TJSonStreamObject;
  lvFile:String;
begin
  lvJsonStream := TJSonStreamObject(pvDataObject);

  //客户端发送文件
  if lvJsonStream.JSon.I['cmdIndex'] = 102 then
  begin
    lvFile := ExtractFilePath(ParamStr(0)) + 'tempFile\';
    ForceDirectories(lvFile);
    lvFile := lvFile + lvJsonStream.JSon.S['file'];
    TMemoryStream(lvJsonStream.Stream).Position := 0;
    TMemoryStream(lvJsonStream.Stream).SaveToFile(lvFile);
  end;


  TLogClientWrapper.logINfo(lvJsonStream.JSon.AsJSon(True));

end;

 

 

代码比较简单

我还是把我的demo贴出来<还是放在360云盘上面>

Delphi-IOCP源码下载

目录
相关文章
|
机器学习/深度学习 C# 算法
带你读《C#神经网络编程》之一:快速预览
本书旨在为C#程序员使用神经网络、CNTK等C#库和TensorFlowSharp解决复杂的计算问题时,提供实践指导。本书从神经网络入门知识开始,详细介绍如何使用Encog、Aforge和Accord搭建一个神经网络,帮助你深入理解神经网络相关概念和技术,例如深度网络、感知器、优化算法、卷积网络和自动解码器。此外,还详细讲解如何向.NET应用程序中添加智能特性,例如面部和运动检测、对象检测和标注、语言理解、知识和智能搜索。
|
8月前
|
编解码
AVFormatContext编解码层:理论与实战(二)
AVFormatContext编解码层:理论与实战(二)
67 0
|
8月前
|
编解码 内存技术
AVFormatContext编解码层:理论与实战(三)
AVFormatContext编解码层:理论与实战(三)
57 0
|
6月前
IEC104初学者教程,第七章:传送原因语义归总
传送原因(Cause of Transmission, COT)是该协议中的一个重要字段,用于描述报文的传送目的或触发事件。 这些代码有助于接收方理解报文的意图和上下文,并做出相应的处理。例如,如果接收到的报文的传送原因是“周期”,接收方可以理解这是一个定期传输的状态信息,而如果传送原因是“突发”,则表示这是一个紧急事件需要立即处理。
88 2
|
7月前
|
存储 机器学习/深度学习 索引
程序与技术分享:DataStage中Transformer的函数大全
程序与技术分享:DataStage中Transformer的函数大全
|
8月前
|
设计模式
LabVIEW建立生产者消费者
LabVIEW建立生产者消费者
65 3
|
8月前
|
编解码 安全 前端开发
Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读
Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读
273 0
|
8月前
|
网络协议 Linux 数据处理
Linux网络编程(各种协议模型的基础知识)
Linux网络编程(各种协议模型的基础知识)
85 0
|
机器学习/深度学习 存储 人工智能
解码Transformer:自注意力机制与编解码器机制详述与代码实现
解码Transformer:自注意力机制与编解码器机制详述与代码实现
231 0
|
算法 图形学
labview编程笔记之事件结构
labview编程笔记之事件结构
169 0