好久没有写新的东西了, BLOG
都快荒废了。今天有时间来写一写东西了。 以前我已经写了 IOCP
和完成例程的基本思路,都是写的服务端部分。今天我来写一写如何使用事件模型编写一个客户端。 TWorkThread =class;
工作线程类,此类主要用于相应接收、发送和断开等网络事件。 TIOEvents = class; IO
事件类,此类主要用于实际处理。 DEFAULT_BUFSIZE = 1024 * 8;
SIO_KEEPALIVE_VALS = IOC_IN or IOC_VENDOR or 4;
HEAP_ZERO_MEMORY = $00000008;
keepalivetime: Integer; //
间隔时间 keepaliveinterval: Integer; //
在间隔时间中的次数 PTCP_KEEPALIVE = ^TTCP_KEEPALIVE;
TOperation=(IO_ACCEPT,IO_WRITE,IO_READ,IO_CLOSE);
BufferLen:Integer; //
数据长度 Buffer:array[0..DATA_BUFSIZE-1] of char;//
数据信息,包括数据头信息 FNetClass:Pointer; //
类的指针 PSendBuffer = ^TSendBuffer;
DEFAULT_BUFSIZE
为默认数据长度,用来限制每次发送数据包的最大长度。会在发送数据的时候使用到它。 DEFAULT_BUFSIZE
以下的常量和 TTCP_KEEPALIVE
结构都是用做心跳设置的,具体可以看我的 BLOG
中关于心跳的文章。 PIOData
为 IO
结构。其中 FNetClass
用于定义的类指针此指针指向 TIOEvents
。 TOnConnect = procedure of object;
TOnDisConnect = procedure of object;
TOnReceive = procedure(Data: Pchar; DataLen: Integer) of object;
TOnSend = procedure(Data: Pchar; DataLen: Integer) of object;
TOnError = procedure(ErrorID:Integer) of Object;
FSendIOData:TIOData; //
接收和发送的 IO
结构 Sending:Boolean; //
是否正在发送 FLastNode:PSendBuffer; //
发送队列 FTotalCount:Cardinal; //
需要发送的数量 FEventCS:TRTLCriticalSection; //
发送缓冲的临界区 FWorkThread:TWorkThread; //
工作者线程 function SetKPAlive:Boolean; //
开启心跳 function PostRecv:Boolean; //
投递接收 function PostSend:Boolean; //
投递发送 procedure ClearBuffer; //
清空所有发送 BUFFER
具体实现方式我会在后面逐一说明。在这里先说明一下 FSendIOData
结构。对于发送数据来说,我的处理方法是:将数据放入发送队列中。如果当前数据正在发送,则不做处理,如果当前数据已经发送完毕,那么我会检测发送队列中是否还有数据需要发送,如果有,则继续发送。 FEventNums:Word; //
当前事件数量 FEventArray:Array [0..WSA_MAXIMUM_WAIT_EVENTS-1] of WSAEVENT; //
事件数组 FSocketArray:array[0..WSA_MAXIMUM_WAIT_EVENTS - 1] of TSocket; //
套接字数组 FSending:Boolean; //
是否正在发送数据 function SocketWrite(Data: Pchar; DataLen: Integer):Boolean; //
发送数据 property Active:Boolean read FActive write SetActive; //
是否启动 property MainIP:String read FMainIP write SetMainIP; //
服务端 IP
property MainPort:Integer read FMainPort write SetMainPort; //
服务端端口 property SendLen:Cardinal read FSendLen write SetSendLen; //
发送的对大数据长度 property KeepAlive:Boolean read FKeepAlive write SetKeepAlive; //
是否启动 Keepalive
property KeepTime:Word read FKeepTime write SetKeepTime; //Keep
的监听时间 property OnConect:TOnConnect read FOnConect write SetOnConect; //
客户端连接 property OnDisConnect:TOnDisConnect read FOnDisConnect write SetOnDisConnect; //
客户端正常断开 property OnRecive:TOnReceive read FOnRecive write SetOnRecive; //
接收客户端数据 property OnSend:TOnSend read FOnSend write SetOnSend; //
向客户端发送数据 property OnError:TOnError read FOnError write SetOnError; //
返回错误信息 TWorkThread = class(TThread)
{ Protected declarations }
procedure Execute; override;
constructor Create(Parent:TIOEvents);
destructor Destroy; override;
到此,定义类已经定义完成,下篇我将写 TIOEvents
类如何实现。希望我的代码对大家有一定的帮助。 本文转自狗窝博客51CTO博客,原文链接http://blog.51cto.com/fxh7622/159224如需转载请自行联系原作者