统一以太网接口,2860和5500均升级,未测试

统一DHCP,简单测试,成功发出Request,收到Offer,但是程序未处理
This commit is contained in:
nnhy 2015-09-16 10:09:57 +00:00
parent 97c560deae
commit e772547197
23 changed files with 170 additions and 819 deletions

View File

@ -1020,7 +1020,8 @@ void HardSocket::OnClose()
Remote.Show(true);
}
int HardSocket::ReadByteArray(ByteArray& bs)
// 接收数据
uint HardSocket::Receive(ByteArray& bs)
{
// 读取收到数据容量
ushort size = __REV16(SocRegRead2(RX_RSR));
@ -1049,7 +1050,8 @@ int HardSocket::ReadByteArray(ByteArray& bs)
return size;
}
bool HardSocket::WriteByteArray(const ByteArray& bs)
// 发送数据
bool HardSocket::Send(const ByteArray& bs)
{
// 读取状态
byte st = ReadStatus();
@ -1075,7 +1077,7 @@ bool HardSocket::WriteByteArray(const ByteArray& bs)
bool HardSocket::OnWrite(const byte* buf, uint len)
{
ByteArray bs(buf,len);
return WriteByteArray(bs);
return Send(bs);
}
uint HardSocket::OnRead(byte* buf, uint len)
@ -1083,7 +1085,7 @@ uint HardSocket::OnRead(byte* buf, uint len)
ByteArray bs(buf, len);
// 不容 ByteArray 偷梁换柱把buf换掉
return ReadByteArray(bs);
return Receive(bs);
}
void HardSocket::ClearRX()
@ -1120,7 +1122,7 @@ void HardSocket::ReceiveTask(void* param)
assert_ptr(param);
HardSocket* socket = (HardSocket*)param;
socket->Receive();
socket->RaiseReceive();
}
void HardSocket::Register(TransportHandler handler, void* param)
@ -1239,7 +1241,7 @@ void TcpClient::OnProcess(byte reg)
else
{
ByteArray bs;
int size = ReadByteArray(bs);
int size = Receive(bs);
debug_printf("收到数据:");
bs.Show();
debug_printf("\r\n");
@ -1274,10 +1276,10 @@ void TcpClient::OnProcess(byte reg)
}
// 异步中断
void TcpClient::Receive()
void TcpClient::RaiseReceive()
{
ByteArray bs;
int size = ReadByteArray(bs);
int size = Receive(bs);
if(size > 1500)return;
// 回调中断
@ -1308,7 +1310,7 @@ void UdpClient::OnProcess(byte reg)
else
{
ByteArray bs;
int size = ReadByteArray(bs);
int size = Receive(bs);
debug_printf("收到数据:");
bs.Show();
debug_printf("\r\n");
@ -1320,13 +1322,13 @@ void UdpClient::OnProcess(byte reg)
// UDP 异步只有一种情况 收到数据 可能有多个数据包
// UDP接收到的数据结构 RemoteIP(4 byte) + RemotePort(2 byte) + Length(2 byte) + Data(Length byte)
void UdpClient::Receive()
void UdpClient::RaiseReceive()
{
// UDP 异步只有一种情况 收到数据 可能有多个数据包
// UDP接收到的数据结构 RemoteIP(4 byte) + RemotePort(2 byte) + Length(2 byte) + Data(Length byte)
byte buf[1024];
ByteArray bs(buf, ArrayLength(buf));
ushort size = ReadByteArray(bs);
ushort size = Receive(bs);
Stream ms(bs.GetBuffer(), size);
// 拆包
@ -1358,7 +1360,7 @@ void UdpClient::Receive()
// {
// // 读取包头
// ByteArray bsHead(packetHead, ArrayLength(packetHead));
// ushort size = ReadByteArray(bsHead, true);
// ushort size = Receive(bsHead, true);
// if(size == ArrayLength(packetHead))
// {
// // 解析头
@ -1405,7 +1407,7 @@ void UdpClient::Receive()
// if(RemainLength < DataLength) return;
// // 读取数据
// ByteArray bsData(dataBuf, DataLength);
// ushort datasize = ReadByteArray(bsData, true);
// ushort datasize = Receive(bsData, true);
//
// // debug_printf("Data: ");
// // bsData.Show();

View File

@ -11,7 +11,7 @@
class HardSocket;
// W5500以太网驱动
class W5500
class W5500 : public ISocketHost
{
private:
friend class HardSocket;
@ -48,14 +48,6 @@ public:
bool Opened; // 是否已经打开
IPAddress IP; // 本地IP地址
IPAddress Mask; // 子网掩码
MacAddress Mac; // 本地Mac地址
IPAddress DHCPServer;
IPAddress DNSServer;
IPAddress Gateway;
// 构造
W5500();
W5500(Spi* spi, Pin irq = P0 ,Pin rst = P0); // 必须具备复位引脚 否则寄存器不能读
@ -114,9 +106,6 @@ public:
W5500* Host; // W5500公共部分控制器
uint _tidRecv; // 收数据线程
//IPEndPoint Remote; // 远程地址。默认发送数据的目标地址
//IPEndPoint Local; // 本地地址
HardSocket(W5500* host, byte protocol);
virtual ~HardSocket();
@ -127,12 +116,14 @@ public:
virtual bool OnOpen();
virtual void OnClose();
bool WriteByteArray(const ByteArray& bs);
int ReadByteArray(ByteArray& bs);
virtual bool OnWrite(const byte* buf, uint len);
virtual uint OnRead(byte* buf, uint len);
// 发送数据
virtual bool Send(const ByteArray& bs);
// 接收数据
virtual uint Receive(ByteArray& bs);
static void ReceiveTask(void* param);
virtual void Register(TransportHandler handler, void* param);
@ -142,7 +133,7 @@ public:
void Process();
virtual void OnProcess(byte reg) = 0;
// 用户注册的中断事件处理 异步调用
virtual void Receive() = 0;
virtual void RaiseReceive() = 0;
// 清空所有接收缓冲区
void ClearRX();
};
@ -163,7 +154,7 @@ public:
// 中断分发 维护状态
virtual void OnProcess(byte reg);
// 用户注册的中断事件处理 异步调用
virtual void Receive();
virtual void RaiseReceive();
private:
bool Linked;
@ -180,7 +171,7 @@ public:
// 中断分发 维护状态
virtual void OnProcess(byte reg);
// 用户注册的中断事件处理 异步调用
virtual void Receive();
virtual void RaiseReceive();
private:
// 数据包头和数据分开读取

View File

@ -1,20 +1,25 @@
#include "Time.h"
#include "Stream.h"
#include "ITransport.h"
#include "Dhcp.h"
#define NET_DEBUG DEBUG
Dhcp::Dhcp(TinyIP* tip) : UdpSocket(tip)
Dhcp::Dhcp(ISocket* socket)
{
Type = IP_UDP;
Local.Port = 68;
Remote.Port = 67;
Remote.Address = IPAddress::Broadcast();
Socket = socket;
Host = socket->Host;
Running = false;
Result = false;
ExpiredTime = 10;
socket->Local.Port = 68;
socket->Remote.Port = 67;
socket->Remote.Address = IPAddress::Broadcast();
OnStop = NULL;
Running = false;
Result = false;
ExpiredTime = 10;
OnStop = NULL;
}
void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
@ -24,9 +29,9 @@ void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
{
// 此时指向的是负载数据后的第一个字节所以第一个opt不许Next
DHCP_OPT* opt = (DHCP_OPT*)(p + len);
opt = opt->SetClientId(Tip->Mac);
if(!Tip->IP.IsAny())
opt = opt->Next()->SetData(DHCP_OPT_RequestedIP, Tip->IP.Value);
opt = opt->SetClientId(Host->Mac);
if(!Host->IP.IsAny())
opt = opt->Next()->SetData(DHCP_OPT_RequestedIP, Host->IP.Value);
// 构造产品名称把ID第一个字节附到最后
String name;
@ -44,13 +49,12 @@ void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
len = (byte*)opt + 1 - p;
}
//memcpy(dhcp->ClientMac, (byte*)&Tip->Mac.Value, 6);
for(int i=0; i<6; i++)
dhcp.ClientMac[i] = Tip->Mac[i];
dhcp.ClientMac[i] = Host->Mac[i];
//RemoteIP = IPAddress::Broadcast;
Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, Remote.Address, Remote.Port, false);
//Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, Remote.Address, Remote.Port, false);
ByteArray bs((byte*)&dhcp, sizeof(DHCP_HEADER) + len);
Socket->Send(bs);
}
// 获取选项,返回数据部分指针
@ -86,7 +90,7 @@ void Dhcp::Request(DHCP_HEADER& dhcp)
DHCP_OPT* opt = (DHCP_OPT*)p;
opt->SetType(DHCP_TYPE_Request);
opt = opt->Next()->SetData(DHCP_OPT_DHCPServer, Tip->DHCPServer.Value);
opt = opt->Next()->SetData(DHCP_OPT_DHCPServer, Host->DHCPServer.Value);
// 发往DHCP服务器
SendDhcp(dhcp, (byte*)opt->Next() - p);
@ -102,10 +106,10 @@ void Dhcp::PareOption(Stream& ms)
// 有些家用路由器会发送错误的len大于4字节导致覆盖前后数据
switch(opt)
{
case DHCP_OPT_Mask: Tip->Mask = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DNSServer: Tip->DNSServer = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_Router: Tip->Gateway = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DHCPServer: Tip->DHCPServer = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_Mask: Host->Mask = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DNSServer: Host->DNSServer = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_Router: Host->Gateway = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DHCPServer: Host->DHCPServer = ms.Read<int>(); len -= 4; break;
//default:
// debug_printf("Unkown DHCP Option=%d Length=%d\r\n", opt, len);
}
@ -116,13 +120,11 @@ void Dhcp::PareOption(Stream& ms)
void RenewDHCP(void* param)
{
TinyIP* tip = (TinyIP*)param;
if(tip)
ISocket* socket = (ISocket*)param;
if(socket)
{
/*Dhcp dhcp(tip);
dhcp.Start();*/
// 不能使用栈分配,因为是异步操作
Dhcp* dhcp = new Dhcp(tip);
Dhcp* dhcp = new Dhcp(socket);
dhcp->Start();
}
}
@ -135,38 +137,25 @@ void Dhcp::Start()
debug_printf("Dhcp::Start ExpiredTime=%ds DhcpID=0x%08x\r\n", ExpiredTime, dhcpid);
// 创建任务每秒发送一次Discover
//debug_printf("Dhcp发送Discover ");
taskID = Sys.AddTask(SendDiscover, this, 0, 1000000, "DHCP");
// 通过DHCP获取IP期间关闭Arp响应
//Tip->EnableArp = false;
if(Tip->Arp) Tip->Arp->Enable = false;
Running = true;
Open();
ITransport* port = dynamic_cast<ITransport*>(Socket);
if(port) port->Open();
}
void Dhcp::Stop()
{
Close();
ITransport* port = dynamic_cast<ITransport*>(Socket);
if(port) port->Close();
Running = false;
if(taskID)
{
debug_printf("Dhcp发送Discover ");
Sys.RemoveTask(taskID);
}
taskID = 0;
// 通过DHCP获取IP期间关闭Arp响应
//Tip->EnableArp = true;
if(Tip->Arp) Tip->Arp->Enable = true;
Running = false;
Sys.RemoveTask(taskID);
taskID = 0;
debug_printf("Dhcp::Stop Result=%d DhcpID=0x%08x\r\n", Result, dhcpid);
if(Result) Tip->ShowInfo();
if(OnStop) OnStop(this, NULL);
// 销毁自己
@ -213,10 +202,10 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
if(__REV(dhcp->TransID) != dhcpid) return;
IPAddress remote = ip.SrcIP;
if(opt->Data == DHCP_TYPE_Offer)
{
Tip->IP = dhcp->YourIP;
Host->IP = dhcp->YourIP;
Stream optData(dhcp->Next(), len);
PareOption(optData);
@ -224,7 +213,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
// 这里其实还应该发送ARP包确认IP是否被占用如果被占用还需要拒绝服务器提供的IP比较复杂可能性很低暂时不考虑
#if NET_DEBUG
debug_printf("DHCP::Offer IP:");
Tip->IP.Show();
Host->IP.Show();
debug_printf(" From ");
remote.Show();
debug_printf("\r\n");
@ -242,7 +231,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
}
else if(opt->Data == DHCP_TYPE_Ack)
{
Tip->IP = dhcp->YourIP;
Host->IP = dhcp->YourIP;
#if NET_DEBUG
debug_printf("DHCP::Ack IP:");
IPAddress(dhcp->YourIP).Show();
@ -251,7 +240,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
debug_printf("\r\n");
#endif
//if(dhcp->YourIP == Tip->IP)
//if(dhcp->YourIP == Host->IP)
{
// 查找租约时间,提前续约
opt = GetOption(data, len, DHCP_OPT_IPLeaseTime);
@ -266,7 +255,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
if(time > 0)
{
//debug_printf("Dhcp过期获取 ");
Sys.AddTask(RenewDHCP, Tip, (ulong)time / 2 * 1000000, -1, "DHCP超时");
Sys.AddTask(RenewDHCP, Socket, (ulong)time / 2 * 1000000, -1, "DHCP超时");
}
}
@ -282,7 +271,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
// 导致Nak的原因
opt = GetOption(data, len, DHCP_OPT_Message);
debug_printf("DHCP::Nak IP:");
Tip->IP.Show();
Host->IP.Show();
debug_printf(" From ");
remote.Show();
if(opt)

View File

@ -1,10 +1,11 @@
#ifndef _TinyIP_DHCP_H_
#define _TinyIP_DHCP_H_
#include "Udp.h"
#include "Net.h"
#include "Ethernet.h"
// DHCP协议
class Dhcp : public UdpSocket
class Dhcp
{
private:
uint dhcpid;
@ -20,11 +21,14 @@ private:
static void SendDiscover(void* param);
public:
ISocket* Socket;
ISocketHost* Host; // 主机
bool Running; // 正在运行
bool Result; // 是否获取IP成功
uint ExpiredTime; // 过期时间
Dhcp(TinyIP* tip);
Dhcp(ISocket* socket);
void Start(); // 开始
void Stop(); // 停止

View File

@ -98,13 +98,33 @@ public:
static const MacAddress& Full();
};
// Socket主机
class ISocketHost
{
public:
IPAddress IP; // 本地IP地址
IPAddress Mask; // 子网掩码
MacAddress Mac; // 本地Mac地址
IPAddress DHCPServer;
IPAddress DNSServer;
IPAddress Gateway;
};
// Socket接口
class ISocket
{
public:
ISocketHost* Host; // 主机
//ushort Port; // 本地端口。用于过滤数据默认0表示接收所有端口的数据
IPEndPoint Local; // 本地地址。包含本地局域网IP地址实际监听的端口从1024开始累加
IPEndPoint Remote; // 远程地址
// 发送数据
virtual bool Send(const ByteArray& bs) = 0;
// 接收数据
virtual uint Receive(ByteArray& bs) = 0;
};
#endif

View File

@ -19,7 +19,7 @@ public:
ArpSession* _ArpSession;
ArpSocket::ArpSocket(TinyIP* tip) : Socket(tip, IP_NONE)
ArpSocket::ArpSocket(TinyIP* tip) : TinySocket(tip, IP_NONE)
{
//Type = IP_NONE;

View File

@ -4,7 +4,7 @@
#include "TinyIP.h"
// ARP协议
class ArpSocket : public Socket
class ArpSocket : public TinySocket
{
private:
// ARP表

View File

@ -33,7 +33,7 @@ public:
// 用于等待Ping响应的会话
PingSession* _IcmpSession = NULL;
IcmpSocket::IcmpSocket(TinyIP* tip) : Socket(tip, IP_ICMP)
IcmpSocket::IcmpSocket(TinyIP* tip) : TinySocket(tip, IP_ICMP)
{
//Type = IP_ICMP;

View File

@ -7,7 +7,7 @@
#include "TinyIP.h"
// ICMP协议
class IcmpSocket : public Socket
class IcmpSocket : public TinySocket
{
public:
IcmpSocket(TinyIP* tip);

View File

@ -8,7 +8,7 @@ bool* WaitAck;
bool Callback(TinyIP* tip, void* param, Stream& ms);
TcpSocket::TcpSocket(TinyIP* tip) : Socket(tip, IP_TCP)
TcpSocket::TcpSocket(TinyIP* tip) : TinySocket(tip, IP_TCP)
{
//Port = 0;
@ -150,9 +150,9 @@ void TcpSocket::OnAccept(TCP_HEADER& tcp, uint len)
SetMss(tcp);
// 需要用到MSS所以采用4个字节的可选段
//Send(tcp, 4, TCP_FLAGS_SYN | TCP_FLAGS_ACK);
//SendPacket(tcp, 4, TCP_FLAGS_SYN | TCP_FLAGS_ACK);
// 注意tcp->Size()包括头部的扩展数据这里不用单独填4
Send(tcp, 0, TCP_FLAGS_SYN | TCP_FLAGS_ACK);
SendPacket(tcp, 0, TCP_FLAGS_SYN | TCP_FLAGS_ACK);
}
// 客户端收到握手三也是首次收到来自服务端的数据或者0数据的ACK
@ -176,7 +176,7 @@ void TcpSocket::OnAccept3(TCP_HEADER& tcp, uint len)
// 不需要Mss
tcp.Length = sizeof(TCP_HEADER) / 4;
Send(tcp, 0, TCP_FLAGS_ACK);
SendPacket(tcp, 0, TCP_FLAGS_ACK);
}
void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
@ -187,7 +187,7 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
if (tcp.Flags & (TCP_FLAGS_FIN | TCP_FLAGS_RST)) //FIN结束连接请求标志位。为1表示是结束连接的请求数据包
{
SetSeqAck(tcp, 1, true);
Send(tcp, 0, TCP_FLAGS_ACK);
SendPacket(tcp, 0, TCP_FLAGS_ACK);
}
else
{
@ -211,7 +211,7 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
SetSeqAck(tcp, len, true);
// 响应Ack和发送数据一步到位
Send(tcp, len2, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
SendPacket(tcp, len2, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
}
if(OnReceived)
@ -223,7 +223,7 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
{
// 发送ACK通知已收到
SetSeqAck(tcp, len, true);
Send(tcp, 0, TCP_FLAGS_ACK);
SendPacket(tcp, 0, TCP_FLAGS_ACK);
return;
}
}
@ -239,10 +239,10 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
}
// 发送ACK通知已收到
SetSeqAck(tcp, len, true);
Send(tcp, 0, TCP_FLAGS_ACK);
SendPacket(tcp, 0, TCP_FLAGS_ACK);
// 响应Ack和发送数据一步到位
//Send(tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
//SendPacket(tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
}
void TcpSocket::OnDisconnect(TCP_HEADER& tcp, uint len)
@ -256,7 +256,7 @@ void TcpSocket::OnDisconnect(TCP_HEADER& tcp, uint len)
{
SetSeqAck(tcp, 1, true);
//Close(tcp, 0);
Send(tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN);
SendPacket(tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN);
}
else if(!OnDisconnected)
{
@ -271,7 +271,7 @@ void TcpSocket::OnDisconnect(TCP_HEADER& tcp, uint len)
Status = Closed;
}
bool TcpSocket::Send(TCP_HEADER& tcp, uint len, byte flags)
bool TcpSocket::SendPacket(TCP_HEADER& tcp, uint len, byte flags)
{
tcp.SrcPort = __REV16(Local.Port);
tcp.DestPort = __REV16(Remote.Port);
@ -344,7 +344,7 @@ void TcpSocket::SendAck(uint len)
TCP_HEADER* tcp = ms.Retrieve<TCP_HEADER>();
tcp->Init(true);
Send(*tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
SendPacket(*tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
}
bool TcpSocket::Disconnect()
@ -358,10 +358,10 @@ bool TcpSocket::Disconnect()
TCP_HEADER* tcp = ms.Retrieve<TCP_HEADER>();
tcp->Init(true);
return Send(*tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN);
return SendPacket(*tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN);
}
bool TcpSocket::Send(ByteArray& bs)
bool TcpSocket::Send(const ByteArray& bs)
{
if(!Enable)
{
@ -396,7 +396,7 @@ bool TcpSocket::Send(ByteArray& bs)
tcp->Ack = __REV(Ack);
// 发送数据的时候需要同时带PUSH和ACK
//debug_printf("Seq=0x%04x Ack=0x%04x \r\n", Seq, Ack);
if(!Send(*tcp, bs.Length(), TCP_FLAGS_PUSH | TCP_FLAGS_ACK)) return false;
if(!SendPacket(*tcp, bs.Length(), TCP_FLAGS_PUSH | TCP_FLAGS_ACK)) return false;
bool wait = false;
WaitAck = &wait;
@ -420,6 +420,11 @@ bool TcpSocket::Send(ByteArray& bs)
return wait;
}
uint TcpSocket::Receive(ByteArray& bs)
{
return 0;
}
// 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要
bool TcpSocket::Connect(IPAddress& ip, ushort port)
{
@ -451,7 +456,7 @@ bool TcpSocket::Connect(IPAddress& ip, ushort port)
SetMss(*tcp);
Status = SynSent;
if(!Send(*tcp, 0, TCP_FLAGS_SYN))
if(!SendPacket(*tcp, 0, TCP_FLAGS_SYN))
{
Status = Closed;
return false;

View File

@ -4,12 +4,12 @@
#include "TinyIP.h"
// Tcp会话
class TcpSocket : public Socket, public ITransport, public ISocket
class TcpSocket : public TinySocket, public ITransport, public ISocket
{
private:
uint Seq; // 序列号,本地发出数据包
uint Ack; // 确认号,对方发送数据包的序列号+1
public:
// Tcp状态
typedef enum
@ -34,10 +34,15 @@ public:
// 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms);
bool Connect(IPAddress& ip, ushort port); // 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要
bool Send(ByteArray& bs); // 向Socket发送数据可能是外部数据包
// 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要
bool Connect(IPAddress& ip, ushort port);
bool Disconnect(); // 关闭Socket
// 发送数据
virtual bool Send(const ByteArray& bs);
// 接收数据
virtual uint Receive(ByteArray& bs);
// 收到Tcp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包
typedef bool (*TcpHandler)(TcpSocket& socket, TCP_HEADER& tcp, byte* buf, uint len);
TcpHandler OnAccepted;
@ -51,7 +56,7 @@ protected:
void SetSeqAck(TCP_HEADER& tcp, uint ackNum, bool cp_seq);
void SetMss(TCP_HEADER& tcp);
bool Send(TCP_HEADER& tcp, uint len, byte flags);
bool SendPacket(TCP_HEADER& tcp, uint len, byte flags);
virtual void OnProcess(TCP_HEADER& tcp, Stream& ms);
virtual void OnAccept(TCP_HEADER& tcp, uint len);

View File

@ -165,7 +165,7 @@ void TinyIP::Process(Stream& ms)
uint count = Sockets.Count();
for(int i=count-1; i>=0; i--)
{
Socket* socket = Sockets[i];
TinySocket* socket = Sockets[i];
if(socket && socket->Enable)
{
// 必须类型匹配
@ -407,7 +407,7 @@ bool TinyIP::IsBroadcast(const IPAddress& ip)
}
#endif
Socket::Socket(TinyIP* tip, IP_TYPE type)
TinySocket::TinySocket(TinyIP* tip, IP_TYPE type)
{
assert_param2(tip, "空的Tip");
@ -419,7 +419,7 @@ Socket::Socket(TinyIP* tip, IP_TYPE type)
if(type != IP_NONE) tip->Sockets.Add(this);
}
Socket::~Socket()
TinySocket::~TinySocket()
{
assert_param2(Tip, "空的Tip");
@ -428,12 +428,12 @@ Socket::~Socket()
Tip->Sockets.Remove(this);
}
Socket* SocketList::FindByType(ushort type)
TinySocket* SocketList::FindByType(ushort type)
{
uint count = Count();
for(int i=count-1; i>=0; i--)
{
Socket* socket = (*this)[i];
TinySocket* socket = (*this)[i];
if(socket)
{
// 必须类型匹配

View File

@ -13,25 +13,25 @@
class TinyIP;
// 网络数据处理Socket基类
class Socket
class TinySocket
{
public:
TinyIP* Tip; // TinyIP控制器
IP_TYPE Type; // 类型
bool Enable; // 启用
Socket(TinyIP* tip, IP_TYPE type);
virtual ~Socket();
TinySocket(TinyIP* tip, IP_TYPE type);
virtual ~TinySocket();
// 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms) = 0;
};
// Socket列表
class SocketList : public List<Socket*>
class SocketList : public List<TinySocket*>
{
public:
Socket* FindByType(ushort type);
TinySocket* FindByType(ushort type);
};
//class TinyIP;
@ -71,7 +71,7 @@ public:
IPAddress Gateway;
// Arp套接字
Socket* Arp;
TinySocket* Arp;
// 套接字列表。套接字根据类型来识别
SocketList Sockets;

View File

@ -3,7 +3,7 @@
//#define NET_DEBUG DEBUG
#define NET_DEBUG 0
UdpSocket::UdpSocket(TinyIP* tip) : Socket(tip, IP_UDP)
UdpSocket::UdpSocket(TinyIP* tip) : TinySocket(tip, IP_UDP)
{
//Port = 0;
@ -77,16 +77,17 @@ void UdpSocket::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
//if(len2) Write(data, len2);
if(len2)
{
Remote = CurRemote;
ByteArray bs(data, len2);
Send(bs, CurRemote.Address, CurRemote.Port);
Send(bs);
}
if(OnReceived)
{
// 返回值指示是否向对方发送数据包
bool rs = OnReceived(*this, udp, CurRemote, ms);
if(rs && ms.Remain() > 0) Send(udp, len, CurRemote.Address, CurRemote.Port, false);
if(rs && ms.Remain() > 0) SendPacket(udp, len, CurRemote.Address, CurRemote.Port, false);
}
else
{
@ -103,7 +104,7 @@ void UdpSocket::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
}
}
void UdpSocket::Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum)
void UdpSocket::SendPacket(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum)
{
uint tlen = sizeof(UDP_HEADER) + len;
udp.SrcPort = __REV16(Local.Port);
@ -128,22 +129,24 @@ void UdpSocket::Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool
}
// 发送UDP数据到目标地址
void UdpSocket::Send(ByteArray& bs, IPAddress ip, ushort port)
bool UdpSocket::Send(const ByteArray& bs)
{
if(ip.IsAny()) ip = Remote.Address;
if(!port) port = Remote.Port;
//if(ip.IsAny()) ip = Remote.Address;
//if(!port) port = Remote.Port;
byte buf[sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + 256];
Stream ms(buf, ArrayLength(buf));
ms.Seek(sizeof(ETH_HEADER) + sizeof(IP_HEADER));
UDP_HEADER* udp = ms.Retrieve<UDP_HEADER>();
udp->Init(true);
// 复制数据,确保数据不会溢出
ms.Write(bs);
Send(*udp, bs.Length(), ip, port, true);
SendPacket(*udp, bs.Length(), Remote.Address, Remote.Port, true);
return true;
}
bool UdpSocket::OnWrite(const byte* buf, uint len)
@ -153,6 +156,11 @@ bool UdpSocket::OnWrite(const byte* buf, uint len)
return len;
}
uint UdpSocket::Receive(ByteArray& bs)
{
return 0;
}
uint UdpSocket::OnRead(byte* buf, uint len)
{
// 暂时不支持

View File

@ -4,7 +4,7 @@
#include "TinyIP.h"
// Udp会话
class UdpSocket : public Socket, public ITransport, public ISocket
class UdpSocket : public TinySocket, public ITransport, public ISocket
{
private:
@ -24,13 +24,15 @@ public:
typedef bool (*UdpHandler)(UdpSocket& socket, UDP_HEADER& udp, IPEndPoint& remote, Stream& ms);
UdpHandler OnReceived;
// 发送UDP数据到目标地址
void Send(ByteArray& bs, IPAddress ip = IPAddress::Any(), ushort port = 0);
// 发送数据
virtual bool Send(const ByteArray& bs);
// 接收数据
virtual uint Receive(ByteArray& bs);
virtual string ToString();
protected:
void Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum = true);
void SendPacket(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum = true);
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
virtual bool OnOpen();

View File

@ -1,475 +0,0 @@
#include "Time.h"
#include "Dhcp.h"
#define NET_DEBUG DEBUG
// 字节序
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1
#endif
#pragma pack(push) // 保存对齐状态
// 强制结构体紧凑分配空间
#pragma pack(1)
// DHCP头部总长度240=0xF0字节偏移42=0x2A后面可选数据偏移282=0x11A
typedef struct _DHCP_HEADER
{
byte MsgType; // 若是client送给server的封包设为1反向为2
byte HardType; // 以太网1
byte HardLength; // 以太网6
byte Hops; // 若数据包需经过router传送每站加1若在同一网内为0
uint TransID; // 事务ID是个随机数用于客户和服务器之间匹配请求和相应消息
ushort Seconds; // 由用户指定的时间,指开始地址获取和更新进行后的时间
ushort Flags; // 从0-15bits最左一bit为1时表示server将以广播方式传送封包给 client其余尚未使用
IPAddr ClientIP; // 客户机IP
IPAddr YourIP; // 你的IP
IPAddr ServerIP; // 服务器IP
IPAddr RelayIP; // 中继代理IP
byte ClientMac[16]; // 客户端硬件地址
byte ServerName[64]; // 服务器名
byte BootFile[128]; // 启动文件名
uint Magic; // 幻数0x63825363小端0x63538263
void Init(uint dhcpid, bool recursion = false)
{
// 为了安全,清空一次
memset(this, 0, sizeof(this[0]));
MsgType = 1;
HardType = 1;
HardLength = 6;
Hops = 0;
TransID = __REV(dhcpid);
Flags = 0x80; // 从0-15bits最左一bit为1时表示server将以广播方式传送封包给 client其余尚未使用
SetMagic();
// if(recursion) Prev()->Init(recursion);
}
uint Size() { return sizeof(this[0]); }
// uint Offset() { return Prev()->Offset() + Size(); }
// UDP_HEADER* Prev() { return (UDP_HEADER*)((byte*)this - sizeof(UDP_HEADER)); }
byte* Next() { return (byte*)this + Size(); }
void SetMagic() { Magic = 0x63538263; }
bool Valid() { return Magic == 0x63538263; }
}DHCP_HEADER;
// DHCP后面可选数据格式为“代码+长度+数据”
typedef enum
{
DHCP_OPT_Mask = 1,
DHCP_OPT_Router = 3,
DHCP_OPT_TimeServer = 4,
DHCP_OPT_NameServer = 5,
DHCP_OPT_DNSServer = 6,
DHCP_OPT_LOGServer = 7,
DHCP_OPT_HostName = 12,
DHCP_OPT_MTU = 26, // 0x1A
DHCP_OPT_StaticRout = 33, // 0x21
DHCP_OPT_ARPCacheTimeout = 35, // 0x23
DHCP_OPT_NTPServer = 42, // 0x2A
DHCP_OPT_RequestedIP = 50, // 0x32
DHCP_OPT_IPLeaseTime = 51, // 0x33
DHCP_OPT_MessageType = 53, // 0x35
DHCP_OPT_DHCPServer = 54, // 0x36
DHCP_OPT_ParameterList = 55, // 0x37
DHCP_OPT_Message = 56, // 0x38
DHCP_OPT_MaxMessageSize = 57, // 0x39
DHCP_OPT_Vendor = 60, // 0x3C
DHCP_OPT_ClientIdentifier = 61, // 0x3D
DHCP_OPT_End = 255,
}DHCP_OPTION;
typedef enum
{
DHCP_TYPE_Discover = 1,
DHCP_TYPE_Offer = 2,
DHCP_TYPE_Request = 3,
DHCP_TYPE_Decline = 4,
DHCP_TYPE_Ack = 5,
DHCP_TYPE_Nak = 6,
DHCP_TYPE_Release = 7,
DHCP_TYPE_Inform = 8,
}DHCP_MSGTYPE;
typedef struct _DHCP_OPT
{
DHCP_OPTION Option; // 代码
byte Length; // 长度
byte Data; // 数据
struct _DHCP_OPT* Next() { return (struct _DHCP_OPT*)((byte*)this + 2 + Length); }
struct _DHCP_OPT* SetType(DHCP_MSGTYPE type)
{
Option = DHCP_OPT_MessageType;
Length = 1;
Data = type;
return this;
}
struct _DHCP_OPT* SetData(DHCP_OPTION option, ByteArray& bs)
{
Option = option;
Length = bs.Length();
bs.CopyTo(&Data);
return this;
}
struct _DHCP_OPT* SetData(DHCP_OPTION option, String& str)
{
ByteArray bs(str);
return SetData(option, bs);
}
struct _DHCP_OPT* SetData(DHCP_OPTION option, uint value)
{
Option = option;
Length = 4;
memcpy(&Data, (byte*)&value, Length);
// 需要考虑地址对齐问题只有4字节对齐才可以直接使用整数赋值
//*(uint*)&Data = value;
return this;
}
struct _DHCP_OPT* SetClientId(MacAddress& mac)
{
Option = DHCP_OPT_ClientIdentifier;
Length = 1 + 6;
Data = 1; // 类型ETHERNET=1
memcpy(&Data + 1, &mac.Value, 6);
return this;
}
struct _DHCP_OPT* End()
{
Option = DHCP_OPT_End;
return this;
}
}DHCP_OPT;
#pragma pack(pop) // 恢复对齐状态
Dhcp::Dhcp(W5500 * host)
{
assert_ptr(host);
_w5500 = host;
_w5500 -> = IPAddress(0, 0, 0, 0);
_UdpPort = new UdpClient(host);
_UdpPort->Local.Port = 68;
_UdpPort->Remote.Port = 67;
_UdpPort->Remote.Address = IPAddress::Broadcast();
Running = false;
Result = false;
ExpiredTime = 10;
OnStop = NULL;
}
//Dhcp::Dhcp(TinyIP* tip) : UdpSocket(tip)
//{
// Type = IP_UDP;
// Local.Port = 68;
// Remote.Port = 67;
// Remote.Address = IPAddress::Broadcast();
//
// Running = false;
// Result = false;
// ExpiredTime = 10;
//
// OnStop = NULL;
//}
void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
{
byte* p = dhcp.Next();
if(p[len - 1] != DHCP_OPT_End)
{
// 此时指向的是负载数据后的第一个字节所以第一个opt不许Next
DHCP_OPT* opt = (DHCP_OPT*)(p + len);
opt = opt->SetClientId(_w5500->Mac);
if(!_w5500->IP.IsAny())
opt = opt->Next()->SetData(DHCP_OPT_RequestedIP, _w5500->IP.Value);
// 构造产品名称把ID第一个字节附到最后
String name;
name += "WSWL_SmartOS_"; // 产生拷贝效果
name.Append(Sys.ID[0]);
opt = opt->Next()->SetData(DHCP_OPT_HostName, name);
String vendor = "http://www.NewLifeX.com";
opt = opt->Next()->SetData(DHCP_OPT_Vendor, vendor);
byte ps[] = { 0x01, 0x06, 0x03, 0x2b}; // 需要参数 Mask/DNS/Router/Vendor
ByteArray bs(ps, ArrayLength(ps));
opt = opt->Next()->SetData(DHCP_OPT_ParameterList, bs);
opt = opt->Next()->End();
len = (byte*)opt + 1 - p;
}
//memcpy(dhcp->ClientMac, (byte*)&_w5500->Mac.Value, 6);
for(int i=0; i<6; i++)
dhcp.ClientMac[i] = _w5500->Mac[i];
//RemoteIP = IPAddress::Broadcast;
Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, Remote.Address, Remote.Port, false);
}
// 获取选项,返回数据部分指针
DHCP_OPT* GetOption(byte* p, int len, DHCP_OPTION option)
{
byte* end = p + len;
while(p < end)
{
byte opt = *p++;
byte len = *p++;
if(opt == DHCP_OPT_End) return 0;
if(opt == option) return (DHCP_OPT*)(p - 2);
p += len;
}
return 0;
}
// 找服务器
void Dhcp::Discover(DHCP_HEADER& dhcp)
{
byte* p = dhcp.Next();
DHCP_OPT* opt = (DHCP_OPT*)p;
opt->SetType(DHCP_TYPE_Discover);
SendDhcp(dhcp, (byte*)opt->Next() - p);
}
void Dhcp::Request(DHCP_HEADER& dhcp)
{
byte* p = dhcp.Next();
DHCP_OPT* opt = (DHCP_OPT*)p;
opt->SetType(DHCP_TYPE_Request);
opt = opt->Next()->SetData(DHCP_OPT_DHCPServer, _w5500->DHCPServer.Value);
// 发往DHCP服务器
SendDhcp(dhcp, (byte*)opt->Next() - p);
}
void Dhcp::PareOption(Stream& ms)
{
while(ms.Remain())
{
byte opt = ms.Read<byte>();
if(opt == DHCP_OPT_End) break;
byte len = ms.Read<byte>();
// 有些家用路由器会发送错误的len大于4字节导致覆盖前后数据
switch(opt)
{
case DHCP_OPT_Mask: _w5500->Mask = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DNSServer: _w5500->DNSServer = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_Router: _w5500->Gateway = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DHCPServer: _w5500->DHCPServer = ms.Read<int>(); len -= 4; break;
//default:
// debug_printf("Unkown DHCP Option=%d Length=%d\r\n", opt, len);
}
// DNS可能有多个IP就不止4长度了
if(len > 0) ms.Seek(len);
}
}
void RenewDHCP(void* param)
{
TinyIP* tip = (TinyIP*)param;
if(tip)
{
/*Dhcp dhcp(tip);
dhcp.Start();*/
// 不能使用栈分配,因为是异步操作
Dhcp* dhcp = new Dhcp(tip);
dhcp->Start();
}
}
void Dhcp::Start()
{
_expiredTime = Time.Current() + ExpiredTime * 1000000;
dhcpid = (uint)Time.Current();
debug_printf("Dhcp::Start ExpiredTime=%ds DhcpID=0x%08x\r\n", ExpiredTime, dhcpid);
// 创建任务每秒发送一次Discover
//debug_printf("Dhcp发送Discover ");
taskID = Sys.AddTask(SendDiscover, this, 0, 1000000, "DHCP");
// 通过DHCP获取IP期间关闭Arp响应
//_w5500->EnableArp = false;
if(_w5500->Arp) _w5500->Arp->Enable = false;
Running = true;
Open();
}
void Dhcp::Stop()
{
Close();
Running = false;
if(taskID)
{
debug_printf("Dhcp发送Discover ");
Sys.RemoveTask(taskID);
}
taskID = 0;
// 通过DHCP获取IP期间关闭Arp响应
//_w5500->EnableArp = true;
if(_w5500->Arp) _w5500->Arp->Enable = true;
debug_printf("Dhcp::Stop Result=%d DhcpID=0x%08x\r\n", Result, dhcpid);
if(Result) _w5500->ShowInfo();
if(OnStop) OnStop(this, NULL);
// 销毁自己
delete this;
}
void Dhcp::SendDiscover(void* param)
{
Dhcp* _dhcp = (Dhcp*)param;
if(!_dhcp->Running) return;
// 检查总等待时间
if(_dhcp->_expiredTime < Time.Current())
{
_dhcp->Stop();
return;
}
byte buf[/*sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + */sizeof(DHCP_HEADER) + 100];
Stream ms(buf, ArrayLength(buf));
//ms.Seek(sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER));
DHCP_HEADER* dhcp = ms.Retrieve<DHCP_HEADER>();
// 向DHCP服务器广播
debug_printf("DHCP::Discover...\r\n");
// dhcp->Init(_dhcp->dhcpid, true);
_dhcp->Discover(*dhcp);
}
void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
{
DHCP_HEADER* dhcp = (DHCP_HEADER*)udp.Next();
if(!dhcp->Valid()) return;
byte* data = dhcp->Next();
uint len = ms.Remain();
// 获取DHCP消息类型
DHCP_OPT* opt = GetOption(data, len, DHCP_OPT_MessageType);
if(!opt) return;
// 所有响应都需要检查事务ID
if(__REV(dhcp->TransID) != dhcpid) return;
IPAddress remote = ip.SrcIP;
if(opt->Data == DHCP_TYPE_Offer)
{
_w5500->IP = dhcp->YourIP;
Stream optData(dhcp->Next(), len);
PareOption(optData);
// 向网络宣告已经确认使用哪一个DHCP服务器提供的IP地址
// 这里其实还应该发送ARP包确认IP是否被占用如果被占用还需要拒绝服务器提供的IP比较复杂可能性很低暂时不考虑
#if NET_DEBUG
debug_printf("DHCP::Offer IP:");
_w5500->IP.Show();
debug_printf(" From ");
remote.Show();
debug_printf("\r\n");
#endif
// 独立分配缓冲区进行操作,避免数据被其它线程篡改
byte buf[sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + sizeof(DHCP_HEADER) + 100];
Stream ms(buf, ArrayLength(buf));
ms.Seek(sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER));
DHCP_HEADER* dhcp2 = ms.Retrieve<DHCP_HEADER>();
dhcp2->Init(dhcpid, true);
Request(*dhcp2);
}
else if(opt->Data == DHCP_TYPE_Ack)
{
_w5500->IP = dhcp->YourIP;
#if NET_DEBUG
debug_printf("DHCP::Ack IP:");
IPAddress(dhcp->YourIP).Show();
debug_printf(" From ");
remote.Show();
debug_printf("\r\n");
#endif
//if(dhcp->YourIP == _w5500->IP)
{
// 查找租约时间,提前续约
opt = GetOption(data, len, DHCP_OPT_IPLeaseTime);
if(opt)
{
// 续约时间,大字节序,时间单位秒
uint time = __REV(*(uint*)&opt->Data);
debug_printf("DHCP IPLeaseTime:%ds\r\n", time);
// DHCP租约过了一半以后重新获取IP地址
if(time > 0)
{
//debug_printf("Dhcp过期获取 ");
Sys.AddTask(RenewDHCP, _w5500, (ulong)time / 2 * 1000000, -1, "DHCP超时");
}
}
//return true;
Result = true;
// 完成任务
Stop();
}
}
#if NET_DEBUG
else if(opt->Data == DHCP_TYPE_Nak)
{
// 导致Nak的原因
opt = GetOption(data, len, DHCP_OPT_Message);
debug_printf("DHCP::Nak IP:");
_w5500->IP.Show();
debug_printf(" From ");
remote.Show();
if(opt)
{
debug_printf(" ");
Sys.ShowString(&opt->Data, opt->Length);
}
debug_printf("\r\n");
}
else
debug_printf("DHCP::Unkown Type=%d\r\n", opt->Data);
#endif
}

View File

@ -1,81 +0,0 @@
#ifndef _TinyIP_DHCP_H_
#define _TinyIP_DHCP_H_
#include "Udp.h"
/*
// DHCP协议
class Dhcp : public UdpSocket
{
private:
uint dhcpid;
uint taskID;
ulong _expiredTime;
ulong _nextTime;
void Discover(DHCP_HEADER& dhcp);
void Request(DHCP_HEADER& dhcp);
void PareOption(Stream& bs);
void SendDhcp(DHCP_HEADER& dhcp, uint len);
static void SendDiscover(void* param);
public:
bool Running; // 正在运行
bool Result; // 是否获取IP成功
uint ExpiredTime; // 过期时间
Dhcp(TinyIP* tip);
void Start(); // 开始
void Stop(); // 停止
EventHandler OnStop;
protected:
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
};
*/
class Dhcp
{
Dhcp(W5500 * host);
public:
DHCP_HEADER * dhcpdata;
private:
W5500 * _w5500;
UDPClient * _UdpPort;
uint dhcpid;
uint taskID;
ulong _expiredTime;
ulong _nextTime;
void Discover(DHCP_HEADER& dhcp);
void Request(DHCP_HEADER& dhcp);
void PareOption(Stream& bs);
void SendDhcp(DHCP_HEADER& dhcp, uint len);
static void SendDiscover(void* param);
public:
bool Running; // 正在运行
bool Result; // 是否获取IP成功
uint ExpiredTime; // 过期时间
Dhcp(TinyIP* tip);
void Start(); // 开始
void Stop(); // 停止
EventHandler OnStop;
protected:
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
};
#endif

View File

@ -1,12 +0,0 @@
#include "Tcp.h"
#define NET_DEBUG 0
//#define NET_DEBUG DEBUG
/*
A=>B SYN
B=>A SYN+ACK
A=>B ACK
*/

View File

@ -1,65 +0,0 @@
#ifndef _TinyIP_TCP_H_
#define _TinyIP_TCP_H_
#include "W5500.h"
// Tcp会话
class TcpSocket : public HardwareSocket, public ITransport
{
public:
// Tcp状态
typedef enum
{
Closed = 0,
SynSent = 1,
SynAck = 2,
Established = 3,
}TCP_STATUS;
ushort Port; // 本地端口接收该端口数据包。0表示接收所有端口的数据包
ushort BindPort; // 绑定端口用于发出数据包的源端口。默认为Port若Port为0则从1024算起累加
IPEndPoint Remote; // 远程地址。默认发送数据的目标地址
IPEndPoint Local; // 本地地址
TCP_STATUS Status; // 状态
TCP_HEADER* Header;
TcpSocket(W5500* pw5500):HardwareSocket(pw5500);
// 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms);
bool Connect(IPAddress& ip, ushort port); // 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要
bool Send(ByteArray& bs); // 向Socket发送数据可能是外部数据包
bool Disconnect(); // 关闭Socket
// 收到Tcp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包
typedef bool (*TcpHandler)(TcpSocket& socket, TCP_HEADER& tcp, byte* buf, uint len);
TcpHandler OnAccepted;
TcpHandler OnReceived;
TcpHandler OnDisconnected;
virtual string ToString();
protected:
void SendAck(uint len);
void SetSeqAck(TCP_HEADER& tcp, uint ackNum, bool cp_seq);
void SetMss(TCP_HEADER& tcp);
bool Send(TCP_HEADER& tcp, uint len, byte flags);
virtual void OnProcess(TCP_HEADER& tcp, Stream& ms);
virtual void OnAccept(TCP_HEADER& tcp, uint len);
virtual void OnAccept3(TCP_HEADER& tcp, uint len);
virtual void OnDataReceive(TCP_HEADER& tcp, uint len);
virtual void OnDisconnect(TCP_HEADER& tcp, uint len);
virtual bool OnOpen();
virtual void OnClose();
virtual bool OnWrite(const byte* buf, uint len);
virtual uint OnRead(byte* buf, uint len);
};
#endif

View File

@ -1,4 +0,0 @@
#include "Udp.h"
//#define NET_DEBUG DEBUG
#define NET_DEBUG 0

View File

@ -1,43 +0,0 @@
#ifndef _TinyIP_UDP_H_
#define _TinyIP_UDP_H_
#include "W5500.h"
// Udp会话
class UdpSocket : public Socket, public ITransport
{
private:
public:
ushort Port; // 本地端口接收该端口数据包。0表示接收所有端口的数据包
ushort BindPort; // 绑定端口用于发出数据包的源端口。默认为Port若Port为0则从1024算起累加
IPEndPoint Remote; // 远程地址。默认发送数据的目标地址
IPEndPoint CurRemote; // 远程地址。本次收到数据的远程地址
IPEndPoint CurLocal; // 本地地址
UdpSocket(W5500* pw5500):HardwareSocket(pw5500);
// 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms);
// 收到Udp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包
typedef bool (*UdpHandler)(UdpSocket& socket, UDP_HEADER& udp, IPEndPoint& remote, Stream& ms);
UdpHandler OnReceived;
// 发送UDP数据到目标地址
void Send(ByteArray& bs, IPAddress ip = IPAddress::Any, ushort port = 0);
virtual string ToString();
protected:
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 bool OnOpen();
virtual void OnClose();
virtual bool OnWrite(const byte* buf, uint len);
virtual uint OnRead(byte* buf, uint len);
};
#endif

View File

@ -462,7 +462,12 @@ void TokenController::ShowStat()
{
ByteArray bs(str);
//debug_printf("握手广播 ");
udp->Send(bs, IPAddress::Broadcast(), 514);
//udp->Send(bs, IPAddress::Broadcast(), 514);
IPEndPoint ep = udp->Remote;
udp->Remote.Port = 514;
udp->Remote.Address = IPAddress::Broadcast();
udp->Send(bs);
udp->Remote = ep;
}
}