请问关于TcpServer接受二进制数据 (50分)

  • 主题发起人 主题发起人 blacksnow
  • 开始时间 开始时间
B

blacksnow

Unregistered / Unconfirmed
GUEST, unregistred user!
我用TcpServer接受二进制数据,数据每次都不定长,请问TcpServer的ClientSocket.Receivebuf函数的参数怎么定义和使用,请给个具体例子,谢谢!
 
定义一个包格式
Type
TBufferType=Array [1..1] of Byte;
PBufferType=^TBufferType;

DataBuf=Record
Size:LongWord;
Data:TBufferType;
End;
发送:
procedure SendQueue.SendAudio;
Var
s:LongWord;
p1:^DataBuf;
Temp:Array[1..5*1024] of Byte;
str:String;
begin
If NOT Terminated Then
Begin
If FAudioQueue.Count>0 Then
Begin
p1:=FAudioQueue.Pop;
Try
If MainForm.IdTCPClient.Connected Then
Begin
s:=p1^.Size+4+4;
System.Str(s,str);
FillChar(Temp,4,0);
Move(p1^,Temp[5],p1^.Size+4);
MainForm.IdTCPClient.WriteLn('D'+str);
MainForm.IdTCPClient.WriteBuffer(Temp,s,True);
End;
Finally
FreeMem(p1);
End;
End;
End;
end;
接受:
procedure TMainForm.IdTCPServerExecute(AThread: TIdPeerThread);
Var
s:String;
ds,s1,s2:LongWord;
code:Integer;
temp:array[1..20*1024] of Byte;
p,p1:^DataBuf;
begin
s:=AThread.Connection.ReadLn;
If s[1]<>'D' Then Exit;
Delete(s,1,1);
Val(s,ds,code);
AThread.Connection.ReadBuffer(temp,ds);
Move(temp,s1,4);
If s1<>0 Then
Begin
GetMem(p,s1+4);
Move(Temp,p^,s1+4);
CodedFrame1.Push(p);
VDC.Execute;
End;
Move(Temp[4+s1+1],s2,4);
GetMem(p1,s2+4);
Move(Temp[4+s1+1],p1^,s2+4);
OriAudio1.Push(p1);
end;

 
定义一个包头,包头中包含包体的长度。

这样一个成对的 包头和包体 就可以实现 不定长发送了
 
二位壮士,是这样,有个软件,它2个部分,一个采集数据,通过2000端口通讯,我想知道数据的内容,就给它修改了,采集的往2001发,我的程序在中间,收到发往2000端口,并且显示一下,接受的测试代码如下:

procedure TForm1.TcpServer1Accept(Sender: TObject;
ClientSocket: TCustomIpClient);
var
s: string;
nSize,i,value:integer;
buffer:Array[0..7] of byte;
begin
nSize:=ClientSocket.ReceiveBuf(buffer,sizeof(buffer));//BufferSize

for i:=0 to nSize-1 do
begin
Value := ord(chr(buffer));
if Value < 16 then
S:=S+'0'+inttohex(Value,1)+' '
else
S:=S+inttohex(Value,1)+' ';
end;

//s := ClientSocket.Receiveln;
memo1.lines.Add(s);
end;

ClientSocket.ReceiveBuf的参数我没有搞清楚,buffer应该是动态数组才行,怎么知道接受的数据长度?d5的serversocket可以这样 ReceviceLength := socket.ReceiveLength; 读出包长度,d7的TcpServer如何知道知道包长度?

谢谢!
 
你的目的无非就是想监控客户到服务端之间传输的数据内容吧。你可以看看
我给别人回的帖子,可能符合你的需要。

http://www.delphibbs.com/delphibbs/dispq.asp?lid=2022615
你可以把我的那些代码保存出来,编译运行一下,其中侦听端口可以设为你需要的2001
远程主机和端口设为你需要转发到的主机IP,和端口2000
至于代码中间对数据的处理,你可以自己修改一下,反正关键的读取传输中的数据的部分
已经有了。
 
注意到我的代码吗?
先发送一个longword,是后续数据长度。然后发送数据。

接收时先接收4字节,就是longword,按照它说明的长度去读。

我从来不信任ReceiveLength,不太准。
 
to firstrose:发送数据的那部分不是我写,是别人的可执行文件,我想看它发送什么东西!

to qlj:正在验证你的代码,呵呵!
 
那好
while recv<>-1 do receivebuf
我实验过,用这个方法可以把数据全部收下来。没有丢包现象.
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
896
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部