发送端创建一个发送缓冲区,用 AddSendBuffer(AData:Pointer;ALen:Integer) 的方式将用户数据包加入到缓冲区.用另一个线程,从缓冲区的另一头取定长,比如说是 1024字节点长度的数据,加上包头形成一个发送数据包。
接收端也是创建一个接收缓冲区,将收到的每个发送数据包中的用户数据都按顺序放在缓冲区中。一个线程根据数据内容来确定是否接收完成一个用户数据包。完成后就给上层应用程序发一个消息。应用程序取到数据后将缓冲区中的对应数据删除。 600) this.width = 600;">
缓冲区中数据头的位置 画错了,应该在绿色的后面。在要加数据就加到绿色的后面,如果缓冲区满了,就从头开始,如果前面也没有空位了,就将缓冲区扩大,或暂停向缓冲区中加数据。
上面是发送缓冲区,里面的每个颜色是用户数据包。
发送线程只按固定的大小A 从缓冲区中取数据,加上顺序号和数据大小A(如果最后缓冲区数据大小比A小,则保存实际的数据大小),形成发送数据包。
接收端收到数据后,检查收到的数据中有多少个发送数据包,将数据包中的数据按顺序放在接收缓冲区中,如果发送数据包让截断了,则等一下个接收事件中取得后面的内容。
检查到形成了一个用户数据包了,则给上层应用发消息。
里面主要用户的就是内存指针的移动,复制,删除的操作。缓冲区其实是个循环队列。
要注意在向缓冲区添加数据的时候要用临界区进行锁定,因为同时发送线程还在读取数据。
接收缓冲区也是同样的。
将发送缓冲区和接收缓冲区和实现成一类使用就更方便了。
PuserInfo=^TuserInfo;
TuserInfo=packed record
A:Array[0..3] of Char;
B:TDateTime;
C:Integer;
D:Array[0..3] of Char;
end;
TUserPack=packed record
PackType:Integer;
DataSize:Integer;
Data:TuserInfo;
end;
function SendUserInfo(Value:TuserInfo):Integer;
var
UserPack:TUserPack;
begin
UserPack.PackType:=1234; //每个类型的包的类型编号是唯一的
UserPack.DataSize:=SizeOf(TuserInfo);
UserPack.Data:=Value;
//添加到发送缓冲区
end;
//收到数据后根据 PackType和 DataSize来确定数据包的大小。