其实是楼主没有搞明白异步通信是怎么一回事和 Onread 事件的触发时机,例如你发送啦 100KB 的数据,此时,每次数据包抵客户端并在系统缓存中累计储存到一定大小时都会触发一次FD_READ 网络事件,在TClientSocket中则触发 OnRead 事件,也就是说如果客户端每次累计接受到 5KB 数据时就触发一次 OnRead 事件,那么就要触发 20 次 OnRead 事件,而且由于网络带宽和系统处理延迟的缘故,所以有可能每次触发 ONRead 事件的间隔时间和实际接受的数据的大小也是不一样的。
相关的代码可以看看以前阻塞和与非阻塞的讨论,在 TCP 协议下要想知道是否为完整接受到请求数据包,可以通过两种方式来处理,第一种是通过自定义数据流边界来确定以及接受完服务器端发送来的数据,第二种是服务器发送完毕后,调用断开命令,这样客户端也就知道数据已经接受完毕。
另外至于缓存数组那种定义方式也是有问题的,一般还是使用指针的方式比较好。
例如:
定义
FReceiveBuf: PChar; //接收数据缓存指针
FReceiveSize: integer; //接收数据缓存的大小
FReceiveCount: integer; //接收到的数据字节计数(总共接收多少数据)
初始化:
FReceiveCount := 0;
FReceiveSize := 1024 * 16; // 16KB 的字节
if not Assigned(FReceiveBuf) then
GetMem(FReceiveBuf, FReceiveSize);
释放:
if Assigned(FReceiveBuf) then
begin
FreeMem(FReceiveBuf, FReceiveSize);
FReceiveBuf := nil;
end;
在 OnRead 事件:
NewLen := FReceiveCount + FClientSocket.ReceiveLength;
if NewLen >= FReceiveSize then
begin
if NewLen < (FReceiveSize + (1024 * 16)) then //按照 16 KB 字节递增分配字节
NewLen := FReceiveSize + (1024 * 16);
ReallocMem(FReceiveBuf, NewLen);
FReceiveSize := NewLen;
end;
Len := FClientSocket.ReceiveBuf(FReceiveBuf[FReceiveCount],
FReceiveSize - FReceiveCount - 1);
...相关判断数据边界或者其他处理方式。