UDP收发数据时指定目标地址端口,避免UdpSocket的远程地址因为收到数据包而被修改

This commit is contained in:
nnhy 2015-06-23 03:53:27 +00:00
parent d77206f7a6
commit d8051b24ab
5 changed files with 27 additions and 25 deletions

View File

@ -7,6 +7,7 @@ Dhcp::Dhcp(TinyIP* tip) : UdpSocket(tip)
Type = IP_UDP; Type = IP_UDP;
Port = 68; Port = 68;
RemotePort = 67; RemotePort = 67;
RemoteIP = IPAddress::Broadcast;
Running = false; Running = false;
Result = false; Result = false;
@ -45,9 +46,9 @@ void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
for(int i=0; i<6; i++) for(int i=0; i<6; i++)
dhcp.ClientMac[i] = Tip->Mac[i]; dhcp.ClientMac[i] = Tip->Mac[i];
RemoteIP = IPAddress::Broadcast; //RemoteIP = IPAddress::Broadcast;
Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, false); Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, IPAddress::Broadcast, RemotePort, false);
} }
// 获取选项,返回数据部分指针 // 获取选项,返回数据部分指针

View File

@ -49,13 +49,13 @@ bool UdpSocket::Process(IP_HEADER& ip, Stream& ms)
if(!udp) return false; if(!udp) return false;
ushort port = __REV16(udp->DestPort); ushort port = __REV16(udp->DestPort);
ushort remotePort = __REV16(udp->SrcPort); //ushort remotePort = __REV16(udp->SrcPort);
// 仅处理本连接的IP和端口 // 仅处理本连接的IP和端口
if(Port != 0 && port != Port) return false; if(Port != 0 && port != Port) return false;
RemotePort = remotePort; //RemotePort = remotePort;
RemoteIP = ip.SrcIP; //RemoteIP = ip.SrcIP;
LocalPort = port; LocalPort = port;
LocalIP = ip.DestIP; LocalIP = ip.DestIP;
@ -86,18 +86,21 @@ void UdpSocket::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
// 如果有返回,说明有数据要回复出去 // 如果有返回,说明有数据要回复出去
if(len2) Write(data, len2); if(len2) Write(data, len2);
IPAddress addr = ip.SrcIP;
IPEndPoint remote(addr, __REV16(udp.SrcPort));
if(OnReceived) if(OnReceived)
{ {
// 返回值指示是否向对方发送数据包 // 返回值指示是否向对方发送数据包
bool rs = OnReceived(*this, udp, ms); bool rs = OnReceived(*this, udp, remote, ms);
if(rs && ms.Remain() > 0) Send(udp, len, false); if(rs && ms.Remain() > 0) Send(udp, len, remote.Address, remote.Port, false);
} }
else else
{ {
#if NET_DEBUG #if NET_DEBUG
debug_printf("UDP "); debug_printf("UDP ");
RemoteIP.Show(); remote.Show();
debug_printf(":%d => ", RemotePort); debug_printf(" => ");
LocalIP.Show(); LocalIP.Show();
debug_printf(":%d Payload=%d udp_len=%d \r\n", LocalPort, len, __REV16(udp.Length)); debug_printf(":%d Payload=%d udp_len=%d \r\n", LocalPort, len, __REV16(udp.Length));
@ -107,34 +110,31 @@ void UdpSocket::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
} }
} }
void UdpSocket::Send(UDP_HEADER& udp, uint len, bool checksum) void UdpSocket::Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum)
{ {
uint tlen = sizeof(UDP_HEADER) + len; uint tlen = sizeof(UDP_HEADER) + len;
udp.SrcPort = __REV16(Port > 0 ? Port : LocalPort); udp.SrcPort = __REV16(Port > 0 ? Port : LocalPort);
udp.DestPort = __REV16(RemotePort); udp.DestPort = __REV16(port);
udp.Length = __REV16(tlen); udp.Length = __REV16(tlen);
// 网络序是大端 // 网络序是大端
udp.Checksum = 0; udp.Checksum = 0;
if(checksum) udp.Checksum = __REV16(Tip->CheckSum(&RemoteIP, (byte*)&udp, tlen, 1)); if(checksum) udp.Checksum = __REV16(Tip->CheckSum(&ip, (byte*)&udp, tlen, 1));
debug_printf("SendUdp: len=%d(0x%x) %d => ", tlen, tlen, __REV16(udp.SrcPort)); debug_printf("SendUdp: len=%d(0x%x) %d => ", tlen, tlen, __REV16(udp.SrcPort));
RemoteIP.Show(); ip.Show();
debug_printf(":%d ", RemotePort); debug_printf(":%d ", port);
if(tlen > 0) Sys.ShowHex(udp.Next(), tlen > 64 ? 64 : tlen, false); if(tlen > 0) Sys.ShowHex(udp.Next(), tlen > 64 ? 64 : tlen, false);
debug_printf("\r\n"); debug_printf("\r\n");
Tip->SendIP(IP_UDP, RemoteIP, (byte*)&udp, tlen); Tip->SendIP(IP_UDP, ip, (byte*)&udp, tlen);
} }
// 发送UDP数据到目标地址 // 发送UDP数据到目标地址
void UdpSocket::Send(ByteArray& bs, IPAddress& ip, ushort port) void UdpSocket::Send(ByteArray& bs, IPAddress& ip, ushort port)
{ {
if(!ip.IsAny()) if(ip.IsAny()) ip = RemoteIP;
{ if(!port) port = RemotePort;
RemoteIP = ip;
RemotePort = port;
}
byte buf[sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + 256]; byte buf[sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + 256];
Stream ms(buf, ArrayLength(buf)); Stream ms(buf, ArrayLength(buf));
@ -149,7 +149,7 @@ void UdpSocket::Send(ByteArray& bs, IPAddress& ip, ushort port)
// 发送的时候采用LocalPort // 发送的时候采用LocalPort
LocalPort = BindPort; LocalPort = BindPort;
Send(*udp, bs.Length(), true); Send(*udp, bs.Length(), ip, port, true);
} }
bool UdpSocket::OnWrite(const byte* buf, uint len) bool UdpSocket::OnWrite(const byte* buf, uint len)

View File

@ -23,7 +23,7 @@ public:
virtual bool Process(IP_HEADER& ip, Stream& ms); virtual bool Process(IP_HEADER& ip, Stream& ms);
// 收到Udp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包 // 收到Udp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包
typedef bool (*UdpHandler)(UdpSocket& socket, UDP_HEADER& udp, Stream& ms); typedef bool (*UdpHandler)(UdpSocket& socket, UDP_HEADER& udp, IPEndPoint& remote, Stream& ms);
UdpHandler OnReceived; UdpHandler OnReceived;
// 发送UDP数据到目标地址 // 发送UDP数据到目标地址
@ -32,7 +32,7 @@ public:
virtual string ToString(); virtual string ToString();
protected: protected:
void Send(UDP_HEADER& udp, uint len, bool checksum = true); void Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum = true);
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms); virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
virtual bool OnOpen(); virtual bool OnOpen();

View File

@ -254,10 +254,11 @@ String& IPAddress::To(String& str)
IPEndPoint::IPEndPoint() IPEndPoint::IPEndPoint()
{ {
Address = IPAddress::Any;
Port = 0; Port = 0;
} }
IPEndPoint::IPEndPoint(IPAddress addr, ushort port) IPEndPoint::IPEndPoint(IPAddress& addr, ushort port)
{ {
Address = addr; Address = addr;
Port = port; Port = port;

2
Type.h
View File

@ -333,7 +333,7 @@ public:
ushort Port; // 端口 ushort Port; // 端口
IPEndPoint(); IPEndPoint();
IPEndPoint(IPAddress addr, ushort port); IPEndPoint(IPAddress& addr, ushort port);
virtual String& To(String& str); virtual String& To(String& str);