最近写一个UDP通信的小程序,使用了INDYUDP系列控件。
消息结构定义如下:
type
TUDP_MSG = record
Head :String[255]; //命令头
PARAM :String[255]; //命令参数
SEQ :String[255]; //指令序列号
Text :String[255]; //文本内容
Time :TDateTime;
StreamSize :Integer; //(StreamData)流的大小
StreamData :TMemoryStream; //数据流,从参数里判断出声音、图象
end;
StreamData是含义不太明确的东西,它有时候可能是文件流,有时候可能是结构体。
//发送代码
msg.Head := 'RNUS';
msg.SEQ := NEOFUN.GetSEQ('GUEST');
msg.Time := Now;
msg.StreamData := TMemoryStream.Create;
//OP是一个结构体,iSizeOfStream是OP的大小
msg.StreamData.WriteBuffer(OP,iSizeOfStream);
msg.StreamSize := iSizeOfStream;
with dmUDP.udpClient do
begin
Host := SVR_IP;
Port := SVR_PORT;
Active := True;
dmUDP.udpClient.SendBuffer(msg,SizeOf(MSG));
end;//接收代码
//MSG --> TUDP_MSG
MSG.StreamData := TMemoryStream.Create;
AData.ReadBuffer(MSG,AData.Size);
if msg.Head = 'RNUS' then //用户注册
try
ShowMessage(IntToStr(MSG.StreamSize));
MSG.StreamData.ReadBuffer(rOP,MSG.StreamSize); *******这里出错******
SHOWmessage(rop.ID);
except
end;搞了几天没搞定,希望高手可以指点指点。不知道发送的时候是不是只发了MSG.StreamData的指针?如果是的话,应该怎样才能把MSG.StreamData 真正发出去 ?
消息结构定义如下:
type
TUDP_MSG = record
Head :String[255]; //命令头
PARAM :String[255]; //命令参数
SEQ :String[255]; //指令序列号
Text :String[255]; //文本内容
Time :TDateTime;
StreamSize :Integer; //(StreamData)流的大小
StreamData :TMemoryStream; //数据流,从参数里判断出声音、图象
end;
StreamData是含义不太明确的东西,它有时候可能是文件流,有时候可能是结构体。
//发送代码
msg.Head := 'RNUS';
msg.SEQ := NEOFUN.GetSEQ('GUEST');
msg.Time := Now;
msg.StreamData := TMemoryStream.Create;
//OP是一个结构体,iSizeOfStream是OP的大小
msg.StreamData.WriteBuffer(OP,iSizeOfStream);
msg.StreamSize := iSizeOfStream;
with dmUDP.udpClient do
begin
Host := SVR_IP;
Port := SVR_PORT;
Active := True;
dmUDP.udpClient.SendBuffer(msg,SizeOf(MSG));
end;//接收代码
//MSG --> TUDP_MSG
MSG.StreamData := TMemoryStream.Create;
AData.ReadBuffer(MSG,AData.Size);
if msg.Head = 'RNUS' then //用户注册
try
ShowMessage(IntToStr(MSG.StreamSize));
MSG.StreamData.ReadBuffer(rOP,MSG.StreamSize); *******这里出错******
SHOWmessage(rop.ID);
except
end;搞了几天没搞定,希望高手可以指点指点。不知道发送的时候是不是只发了MSG.StreamData的指针?如果是的话,应该怎样才能把MSG.StreamData 真正发出去 ?
begin
Host := SVR_IP;
Port := SVR_PORT;
Active := True;
dmUDP.udpClient.SendBuffer(msg,SizeOf(MSG);
dmUDP.udpClient.SendBuffer(OP,iSizeOfStream);
end;
因为msg.StreamData不一定是OP,有可能是声音流或者图片流。
我接收的时候可以从msg.Head分析出msg.StreamData到底是什么,然后作出处理(如果是图片就显示,声音就播放,用户信息结构体就往数据库里面添加一条记录,完成注册操作...)。
如果发两次的话就做不了这个效果了。
其实即使你是一次发送的, 接收方也不一定是在某一次接收事件中能一下子全部接收到的。因为TCP/Ip协议所定义的传输是异步的。这种情况你目前的程序没有处理。而且用UDP传输时,接收到的数据包顺序还不一定是发送时的顺序呢,这种情况比上面的更难解决,你目前的程序也没有处理。
参考:
http://community.csdn.net/Expert/topic/3836/3836430.xml?temp=.6988336
http://community.csdn.net/Expert/topic/3824/3824705.xml?temp=.6447412