自定义数据报头格式
TDataHeader = packed record
PackHeader: array[0..5] of Char; //数据包头
CommandID: Byte; //数据包命令码
DataLen: Integer; //数据内容长度
end;
服务器端代码
procedure TfrmMain.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
I,Count,nDataLen,RecvLen,RecvDataLen: Integer;
SendPauseFlag,IsSendFlag: Boolean;
DataLen, ReadLen, ReadCount, C: Integer;
Buf: PChar;
RDataStream,SDataStream: TMemoryStream;
RDataHeader,SDataHeader: TDataHeader;
begin
RecvLen := Socket.ReceiveLength;
ReadLen := 0;
if RecvLen < DataHeaderSize then Exit;
while ReadLen < RecvLen do
begin
ZeroMemory(@RDataHeader,DataHeaderSize);
RecvDataLen := Socket.ReceiveBuf(RDataHeader,DataHeaderSize);
if RecvDataLen = -1 then
begin
Continue;
end;
ReadLen := ReadLen + RecvDatalen;
GetMem(Buf,RDataHeader.DataLen);
try
RDataStream := TMemoryStream.Create;
try
ReadCount := 0; //读取缓冲区
while ReadCount < RDataHeader.DataLen do
begin
RecvDataLen := Socket.ReceiveBuf(Buf^,RDataHeader.DataLen);
if RecvDataLen = -1 then
begin
Sleep(1);
Continue;
end;
ReadCount := ReadCount + RecvDataLen;
RDataStream.Write(Buf^,RecvDataLen);
end;
ReadLen := ReadLen + ReadCount; //读取数据完成
RDataStream.Position:=0;
if RDataHeader.PackHeader = Header then
begin
//{进行数据处理,并向客户端发送处理完毕应答}
end
finally
RDataStream.Free;
end;
finally
FreeMem(Buf,RDataHeader.DataLen);
end;
end;
end;
客户端代码
procedure TSendWaterThread.Execute;
var
RecordCount,Count:Integer;
ThreadDataHeader: TDataHeader;
SendDataBuffer: array of TDataInfo; //注:TDataInfo为数据内容的记录体,不列出
begin
FreeOnTerminate:=True;
while SystemInfo.ServerConnected do //连接状态
begin
if SystemInfo.CanTransmitFlag then //此值为真则表示已经收到上一次发送数据的应答
begin
//读到要发送的数据
share.SelectSQL(frmDM.adqryNetThread,'select top 64 * from WaterInfo where not TransmitBj order by ID');
RecordCount:=frmDM.adqryNetThread.RecordCount;
if RecordCount>0 then
begin
with ThreadDataHeader do //TDataHeader类型的数据报头
begin
PackHeader:=HeaderStr;
CommandID:=08;
DataLen:=RecordCount*DataInfoSize;
end;
SetLength(SendDataBuffer,ThreadDataHeader.DataLen div DataInfoSize); //
Count:=0;
while not frmDM.adqryNetThread.Eof do
begin
//{将检索出来的数据写入动态记录数组SendDataBuffer}
end;
SystemInfo.CanTransmitFlag:=False;
if frmDM.ClientSocket.Socket.SendBuf(ThreadDataHeader,SizeOf(TDataHeader))=SizeOf(TDataHeader) then
frmMain.Memo1.Lines.Add('thread发送'+IntToStr(Count)+'条记录头成功!'+' '+TimeToStr(Time))
else
frmMain.Memo1.Lines.Add('thread发送'+IntToStr(Count)+'条记录头失败!'+' '+TimeToStr(Time));
if frmDM.ClientSocket.Socket.SendBuf(SendDataBuffer[0],ThreadDataHeader.DataLen)=ThreadDataHeader.DataLen then
frmMain.Memo1.Lines.Add('thread发送'+IntToStr(Count)+'条记录成功!'+' '+TimeToStr(Time))
else
frmMain.Memo1.Lines.Add('thread发送'+IntToStr(Count)+'条记录失败!'+' '+TimeToStr(Time));
end;
end;
end;
end;
大致代码就是这样
客户端的接收代码与服务器类似,接到服务器的应答后就更改 SystemInfo.CanTransmitFlag(可以继续传输标志) 这里就不贴出来了。
虽然我的客户端发送代码没有加重发,可是并没有出现发送记录失败的情况(我在MEMO里面记录了)。
出问题的时候 客户端的MEMO显示发送成功,可服务器的READ就是反应 可这时如果从服务器主动向客户端发送数据,客户端可以正常接收到。
请各位高手帮帮忙 抽点时间给看一下,谢谢了