小弟做了一个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;
***********************************************************************
能有高手指点一下迷津吗?
定义: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;
***********************************************************************
能有高手指点一下迷津吗?
改为UDPSocket.Port :=客户端监听的端口
UDP 服务端与客户端是一个 对等网络
原先怎么发送信息给服务端
服务端新建的一个客户端,返回信息给源客户端(这时可当这个客户端为服务端)
你新建的UDPSocket 应该继承自客户端控件
客户端控件与服务端控件 具体实现好像有点不同
客户端监听的端口=客户路由nat后的端口? 你试下?我觉得应该一样的 我也搞乱了