.........
htons, ntohs是winsock单元,
uses WinSock;即可。
//
// result = 0,表示buf里面的数据不完整
// result > 0, buf数据包正常
// if size > result, 表示buf里面有N个数据包。
//
function GetPacket(const Buf; Size: Integer; var ACmdType: Word; var AData: string): Integer;
var
L: Integer;
cnt: PChar;
hdr: ^TPush_head;
begin
Result := 0;
if Size < SizeOf(TPush_head) then Exit;
hdr := @Buf;
L := ntohs(hdr.myLength);
if Size < SizeOf(TPush_head) + L then Exit;
Result ;= SizeOf(TPush_head) + L;
ACmdType := ntohs(hdr.myType);
cnt := PChar(hdr) + sizeof(TPush_head);
SetString(AData, cnt, L);
end;
recv:
OnClientConnect事件中写上:
var
DataBuffer: PString;
begin
New(DataBuffer);
DataBuffer^ := '';
Socket.Data := DataBuffer;
end;
OnClientDisconnect:
var
DataBuffer: PString;
begin
DataBuffer := Socket.Data;
if DataBuffer <> nil then
begin
Dispose(DataBuffer);
Socket.Data := nil;
end;
OnClientRecv:
procedure WriteBuffer(ABuffer: PString; Data: PChar; Size: Integer);
begin
end;
var
DataBuffer: PString;
Buffer: array [0..1023] of Char;
Size, PacketSize: Integer;
CmdType: Word;
Data: string;
begin
DataBuffer := ClientSocket.socket.data;
// 按理应该不停的去收,这里只写一个收处理,自己改成循环收,只到size=socket_error
size := ClientSocket.socket.recvbuf(buffer[0], sizeof(buffer));
if size > 0 then
WriteBuffer(DataBuffer, buffer, size);
PacketSize := GetPacket(PChar(DataBuffer^), Length(DataBuffer^), CmdType, Data);
// 处理TCP数据流粘包问题。
while PacketSize > 0 do
begin
// OK, 取出CmdType, Data
....
// 删除取出的数据包
Delete(DataBuffer^, 1, PacketSize);
// 再取下一个包
PacketSize := GetPacket(PChar(DataBuffer^), Length(DataBuffer^), CmdType, Data);
end;
end;