客户端C的内网IP及通讯端口为192.168.1.5:7000,对应的经路由NAT后变为220.120.123.42:15000;服务器S的内网IP及通讯端口为192.168.1.150:9119,对应的路由公网IP为113.93.159.242,已经在路由上做了端口映射。
现在C知道S的公网IP及端口113.93.159.242:9119后,向其发送数据,S能收到C的数据,通过函数function TCustomWSocket.ReceiveFrom(
Buffer : Pointer;
BufferSize : Integer;
var From : TSockAddr;
var FromLen : Integer) : integer;知道了C的IP和端口为220.120.123.42:15000;然后向C发送确认数据包,但C却收不到任何数据。
此程序我在同一内网中测试时完全正常的。请教大虾们该如何解决呢?
现在C知道S的公网IP及端口113.93.159.242:9119后,向其发送数据,S能收到C的数据,通过函数function TCustomWSocket.ReceiveFrom(
Buffer : Pointer;
BufferSize : Integer;
var From : TSockAddr;
var FromLen : Integer) : integer;知道了C的IP和端口为220.120.123.42:15000;然后向C发送确认数据包,但C却收不到任何数据。
此程序我在同一内网中测试时完全正常的。请教大虾们该如何解决呢?
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);
//处理数据
If Not ProcessDeviceUDPData(PeerIP,PeerPort,@Buffer,Len) Then
WriteLogMemo('设备UDP服务处理数据失败:'+StrPas(@Buffer));
//
End;
end;//处理UDP数据
function TFrmMain.ProcessDeviceUDPData(PeerIP:String;PeerPort:Integer;AData:Pointer;ADataLength:Integer):Boolean;
var
UDPSocket:TDeviceSocket;
Begin
Result:=False;
//建立
UDPSocket:=GetUDPSocket(PeerIP,PeerPort);
If Not Assigned(UDPSocket) Then
UDPSocket:=TDeviceSocket.Create(DeviceUDPServer);
UDPSocket.Addr:=aAddr;
UDPSocket.Port:=IntToStr(aPort);
UDPSocket.Proto:='udp';
UDPSocket.LineMode:=False;
UDPSocket.LineEdit:=False;
UDPSocket.Connect;
If Assigned(UDPSocket) Then
Begin
通过适当的填充数据包后进行发送
UDPSocket.Send(Dest,DestLen);
End
Else
Begin
WriteLogMemo('建立UDP客户端发生错误!');
End;
End;
改为 ProcessDeviceUDPData(DeviceUDPServer,PeerIP,PeerPort,@Buffer,Len)
发送信息回客户端 用DeviceUDPServer 不用另外创建新的
DeviceUDPServer.Send(PeerIP,PeerPort,Dest,DestLen);//因该有类似的发送函数吧?
那么 客户端 UPDSocket接收信息时 .ReceiveFrom得到的 port 也就对应 5611
客户端根据这个port 返回信息给服务器UPDSocket
但你服务器负责接收监听的 port 是9119
那怎么能接收到数据?同理 客户端 也没有负责接收 来自5611 udpsocket
220.120.123.42:15000 有没有影射到192.168.1.5:7000?
如果影射到,你telent试下有什么?请贴出来。 是用telent 220.120.123.42:15000.
113.93.159.242 的端口是什么? 是9119 吗? 也映射到192.168.1.150:9119吗? 也用telnet试。如果telnet不通,请告诉你用什么做nat的?
请贴出nat内容。
如果是linux下的iptable 做的nat, 俺可以看看。。其他俺不懂。
现在我困惑的是为什么在内网中,新建一个socket发送没问题,而放到公网中就不行了呢?难道客户网关只承认一开始建立的连接socket,而继承新建的socket就认定是不安全的连接吗?UDP传输还真的麻烦啊,TCP就没这样的问题。
而且用 DeviceUDPServer发送时,你还不能直接DeviceUDPServer.Send(Dest,DestLen),这样数据发到客户网关时还会被网关丢掉。必须用DeviceUDPServer.SendTo(Dest:TSockAddr;
DestLen : Integer;
Data: Pointer;
Len: Integer;
) 。