小弟做了一个udp服务器,放在ip为220.56.**.**的公网中,监听的端口为7500。传输协议是udp,使用的是ics中的twsocketserver控件。
        定义:DeviceUDPServer: TWSocketServer;
  DeviceUDPServer.Banner:='';
  DeviceUDPServer.BannerTooBusy:='Busy';
  DeviceUDPServer.Proto:='udp';
  DeviceUDPServer.Addr:='0.0.0.0';
  DeviceUDPServer.Port:=7500;
  DeviceUDPServer.LineMode:=False;
  DeviceUDPServer.LineEdit:=False;
  DeviceUDPServer.Listen;
 现在有一台放在内网中的客户端机器通过公网ip和端口主动访问我的服务器,服务器可以正常接收到数据。
 数据接收函数:
procedure TFrmMain.DeviceUDPServerDataAvailable(Sender: TObject; ErrCode: Word);
var
  Buffer:Array[0..SOCKETBUFFERSIZE-1] Of Char;
  Len    : Integer;
  Src    : TSockAddrIn;
  SrcLen : Integer;
  PeerIP:String;
  PeerPort:Integer;
begin
  //收数据
  SrcLen:=SizeOf(Src);
  ZeroMemory(@Buffer,SOCKETBUFFERSIZE);
  Len:= DeviceUDPServer.ReceiveFrom(@Buffer, SOCKETBUFFERSIZE, Src, SrcLen);
  If Len>0 Then
  Begin
    //得到客户机器的地址和端口
    PeerIP:=StrPas(inet_ntoa(Src.sin_addr));
    PeerPort:=ntohs(Src.sin_port);
    //写日志
    WriteLogMemo('收到UDP数据,来自:'+PeerIP+':'+IntToStr(PeerPort));
    //处理数据
    If Not ProcessDeviceUDPData(PeerIP,PeerPort,@Buffer,Len,Src,SrcLen) Then
      WriteLogMemo('设备UDP服务处理数据失败:'+StrPas(@Buffer));
  End;
end;  问题是服务器发送确认数据包给客户机器时候出现了问题:如果是直接用
  DeviceUDPServer.sendto( Dest: TSockAddr;
                          DestLen : Integer;
                          Data    : Pointer;
                          Len     : Integer) : integer;
 那么可以正常发回给客户机器。
************************************************************************************  但是如果我新建一个socket,如var udpsocket:TDeviceSocket;
                              udpsocket:=TDeviceSocket.create(DeviceUDPServer),
  其中,devicesocket是继承TWSocketClient的一个类,TDeviceSocket=Class(TWSocketClient).
  然后用这个新建的udpsocket进行数据发送,无论是用send还是sendto都发不回去。不知道是不是我在给udpsocket赋值时少了关键的东西还是客户机器拒绝承认这个新建udpsocket。
udpsocket赋值如下:
    UDPSocket.Addr:=客户路由拨号的公网ip;
    UDPSocket.Port:=客户路由nat后的端口;
    UDPSocket.Proto:='udp';
    UDPSocket.LineMode:=False;
    UDPSocket.LineEdit:=False;
***********************************************************************
   能有高手指点一下迷津吗?
  

解决方案 »

  1.   

    UDPSocket.Port:=客户路由nat后的端口
    改为UDPSocket.Port :=客户端监听的端口
    UDP 服务端与客户端是一个 对等网络 
    原先怎么发送信息给服务端 
    服务端新建的一个客户端,返回信息给源客户端(这时可当这个客户端为服务端)
      

  2.   

    改为UDPSocket.Port := 你这个好像是继承自服务端的 这个值可能是监听端口 而不是发送给客户端的端口吧?
    你新建的UDPSocket 应该继承自客户端控件  
    客户端控件与服务端控件 具体实现好像有点不同 
    客户端监听的端口=客户路由nat后的端口? 你试下?我觉得应该一样的 我也搞乱了  
      

  3.   

    hehe ..其实他的问题就在nat里头。