最近写一个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 真正发出去 ?

解决方案 »

  1.   

    不知道发送的时候是不是只发了MSG.StreamData的指针?是的。with dmUDP.udpClient do
    begin
      Host := SVR_IP;
      Port := SVR_PORT;
      Active := True;
      dmUDP.udpClient.SendBuffer(msg,SizeOf(MSG);
      dmUDP.udpClient.SendBuffer(OP,iSizeOfStream);
    end;
      

  2.   

    问题我就是想msg里面包含msg.StreamData(OP),然后只发送一次。
    因为msg.StreamData不一定是OP,有可能是声音流或者图片流。
    我接收的时候可以从msg.Head分析出msg.StreamData到底是什么,然后作出处理(如果是图片就显示,声音就播放,用户信息结构体就往数据库里面添加一条记录,完成注册操作...)。
    如果发两次的话就做不了这个效果了。
      

  3.   

    试试把 StreamData :TMemoryStream;     定义在另外一个结构体里面,再填充数据
      

  4.   

    如果发两次的话就做不了这个效果了。
    其实即使你是一次发送的, 接收方也不一定是在某一次接收事件中能一下子全部接收到的。因为TCP/Ip协议所定义的传输是异步的。这种情况你目前的程序没有处理。而且用UDP传输时,接收到的数据包顺序还不一定是发送时的顺序呢,这种情况比上面的更难解决,你目前的程序也没有处理。
      

  5.   

    StreamData :TMemoryStream; 放在结构体里不合适,发送msg的时候,是把这块连续的缓冲区发送出去,而StreamData是一个指针,数据是存储在其他地方,不是连续的内存空间,所以不能够把里面的内容发送出去。这里应该用其他的办法。
    参考:
    http://community.csdn.net/Expert/topic/3836/3836430.xml?temp=.6988336
    http://community.csdn.net/Expert/topic/3824/3824705.xml?temp=.6447412