使用新的同步等待机制,配合时间轮,避免独占CPU太长时间
This commit is contained in:
parent
4f17a22ab1
commit
d434cbb5a7
|
@ -2,6 +2,22 @@
|
||||||
|
|
||||||
#define NET_DEBUG 0
|
#define NET_DEBUG 0
|
||||||
|
|
||||||
|
class ArpSession
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IPAddress IP;
|
||||||
|
MacAddress Mac;
|
||||||
|
bool Success;
|
||||||
|
|
||||||
|
ArpSession(IPAddress& ip)
|
||||||
|
{
|
||||||
|
IP = ip;
|
||||||
|
Success = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ArpSession* _ArpSession;
|
||||||
|
|
||||||
ArpSocket::ArpSocket(TinyIP* tip) : Socket(tip)
|
ArpSocket::ArpSocket(TinyIP* tip) : Socket(tip)
|
||||||
{
|
{
|
||||||
//Type = ETH_ARP;
|
//Type = ETH_ARP;
|
||||||
|
@ -54,6 +70,13 @@ bool ArpSocket::Process(IP_HEADER& ip, Stream& ms)
|
||||||
// 是否发给本机。
|
// 是否发给本机。
|
||||||
if(arp->DestIP != Tip->IP.Value) return true;
|
if(arp->DestIP != Tip->IP.Value) return true;
|
||||||
|
|
||||||
|
if(arp->Option == 0x0200 && _ArpSession && _ArpSession->IP.Value == arp->SrcIP)
|
||||||
|
{
|
||||||
|
_ArpSession->Mac = arp->SrcMac.Value();
|
||||||
|
_ArpSession->Success = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if NET_DEBUG
|
#if NET_DEBUG
|
||||||
// 数据校验
|
// 数据校验
|
||||||
assert_param(arp->HardType == 0x0100);
|
assert_param(arp->HardType == 0x0100);
|
||||||
|
@ -102,7 +125,7 @@ bool ArpSocket::Process(IP_HEADER& ip, Stream& ms)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestCallback(TinyIP* tip, void* param, Stream& ms)
|
/*bool RequestCallback(TinyIP* tip, void* param, Stream& ms)
|
||||||
{
|
{
|
||||||
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
|
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
|
||||||
ARP_HEADER* arp = ms.Retrieve<ARP_HEADER>();
|
ARP_HEADER* arp = ms.Retrieve<ARP_HEADER>();
|
||||||
|
@ -122,7 +145,7 @@ bool RequestCallback(TinyIP* tip, void* param, Stream& ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// 请求Arp并返回其Mac。timeout超时3秒,如果没有超时时间,表示异步请求,不用等待结果
|
// 请求Arp并返回其Mac。timeout超时3秒,如果没有超时时间,表示异步请求,不用等待结果
|
||||||
bool ArpSocket::Request(IPAddress& ip, MacAddress& mac, int timeout)
|
bool ArpSocket::Request(IPAddress& ip, MacAddress& mac, int timeout)
|
||||||
|
@ -156,7 +179,25 @@ bool ArpSocket::Request(IPAddress& ip, MacAddress& mac, int timeout)
|
||||||
if(timeout <= 0) return false;
|
if(timeout <= 0) return false;
|
||||||
|
|
||||||
// 等待反馈
|
// 等待反馈
|
||||||
if(Tip->LoopWait(RequestCallback, &mac, timeout * 1000)) return true;
|
//if(Tip->LoopWait(RequestCallback, &mac, timeout * 1000)) return true;
|
||||||
|
|
||||||
|
ArpSession ss(ip);
|
||||||
|
_ArpSession = &ss;
|
||||||
|
|
||||||
|
// 等待响应
|
||||||
|
TimeWheel tw(0, timeout * 1000);
|
||||||
|
tw.Sleep = 1;
|
||||||
|
do{
|
||||||
|
if(ss.Success) break;
|
||||||
|
}while(!tw.Expired());
|
||||||
|
|
||||||
|
if(ss.Success)
|
||||||
|
{
|
||||||
|
mac = ss.Mac;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ArpSession = NULL;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,19 @@ public:
|
||||||
Sequence = seq;
|
Sequence = seq;
|
||||||
Success = false;
|
Success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Check(IPAddress& remote, ICMP_HEADER* icmp)
|
||||||
|
{
|
||||||
|
if(remote != Address) return false;
|
||||||
|
if(Identifier != icmp->Identifier) return false;
|
||||||
|
if(Sequence != icmp->Sequence) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 用于等待Ping响应的会话
|
// 用于等待Ping响应的会话
|
||||||
PingSession* Session = NULL;
|
PingSession* _IcmpSession = NULL;
|
||||||
|
|
||||||
IcmpSocket::IcmpSocket(TinyIP* tip) : Socket(tip)
|
IcmpSocket::IcmpSocket(TinyIP* tip) : Socket(tip)
|
||||||
{
|
{
|
||||||
|
@ -38,9 +47,9 @@ bool IcmpSocket::Process(IP_HEADER& ip, Stream& ms)
|
||||||
IPAddress remote = ip.SrcIP;
|
IPAddress remote = ip.SrcIP;
|
||||||
|
|
||||||
// 检查有没有会话等待
|
// 检查有没有会话等待
|
||||||
if(icmp->Type == 0 && Session != NULL && remote == Session->Address)
|
if(icmp->Type == 0 && _IcmpSession != NULL && _IcmpSession->Check(remote, icmp))
|
||||||
{
|
{
|
||||||
Session->Success = true;
|
_IcmpSession->Success = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +89,7 @@ bool IcmpSocket::Process(IP_HEADER& ip, Stream& ms)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PingCallback(TinyIP* tip, void* param, Stream& ms)
|
/*bool PingCallback(TinyIP* tip, void* param, Stream& ms)
|
||||||
{
|
{
|
||||||
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
|
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
|
||||||
IP_HEADER* _ip = ms.Retrieve<IP_HEADER>();
|
IP_HEADER* _ip = ms.Retrieve<IP_HEADER>();
|
||||||
|
@ -102,7 +111,7 @@ bool PingCallback(TinyIP* tip, void* param, Stream& ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Ping目的地址,附带a~z重复的负载数据
|
// Ping目的地址,附带a~z重复的负载数据
|
||||||
bool IcmpSocket::Ping(IPAddress& ip, uint payloadLength)
|
bool IcmpSocket::Ping(IPAddress& ip, uint payloadLength)
|
||||||
|
@ -150,7 +159,7 @@ bool IcmpSocket::Ping(IPAddress& ip, uint payloadLength)
|
||||||
//if(Tip->LoopWait(PingCallback, ps, 1000)) return true;
|
//if(Tip->LoopWait(PingCallback, ps, 1000)) return true;
|
||||||
|
|
||||||
PingSession ps(ip, id, seq);
|
PingSession ps(ip, id, seq);
|
||||||
Session = &ps;
|
_IcmpSession = &ps;
|
||||||
|
|
||||||
// 等待响应
|
// 等待响应
|
||||||
TimeWheel tw(0, 1000);
|
TimeWheel tw(0, 1000);
|
||||||
|
@ -159,7 +168,7 @@ bool IcmpSocket::Ping(IPAddress& ip, uint payloadLength)
|
||||||
if(ps.Success) break;
|
if(ps.Success) break;
|
||||||
}while(!tw.Expired());
|
}while(!tw.Expired());
|
||||||
|
|
||||||
Session = NULL;
|
_IcmpSession = NULL;
|
||||||
|
|
||||||
#if NET_DEBUG
|
#if NET_DEBUG
|
||||||
uint cost = ct.Elapsed() / 1000;
|
uint cost = ct.Elapsed() / 1000;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#define NET_DEBUG 0
|
#define NET_DEBUG 0
|
||||||
//#define NET_DEBUG DEBUG
|
//#define NET_DEBUG DEBUG
|
||||||
|
|
||||||
|
bool* WaitAck;
|
||||||
|
|
||||||
bool Callback(TinyIP* tip, void* param, Stream& ms);
|
bool Callback(TinyIP* tip, void* param, Stream& ms);
|
||||||
|
|
||||||
TcpSocket::TcpSocket(TinyIP* tip) : Socket(tip)
|
TcpSocket::TcpSocket(TinyIP* tip) : Socket(tip)
|
||||||
|
@ -82,6 +84,11 @@ bool TcpSocket::Process(IP_HEADER& ip, Stream& ms)
|
||||||
LocalPort = port;
|
LocalPort = port;
|
||||||
LocalIP = ip.DestIP;
|
LocalIP = ip.DestIP;
|
||||||
|
|
||||||
|
if(WaitAck && (tcp->Flags & TCP_FLAGS_ACK))
|
||||||
|
{
|
||||||
|
*WaitAck = true;
|
||||||
|
}
|
||||||
|
|
||||||
OnProcess(*tcp, ms);
|
OnProcess(*tcp, ms);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -386,9 +393,21 @@ void TcpSocket::Send(ByteArray& bs)
|
||||||
//debug_printf("Seq=0x%04x Ack=0x%04x \r\n", Seq, Ack);
|
//debug_printf("Seq=0x%04x Ack=0x%04x \r\n", Seq, Ack);
|
||||||
Send(*tcp, bs.Length(), TCP_FLAGS_PUSH | TCP_FLAGS_ACK);
|
Send(*tcp, bs.Length(), TCP_FLAGS_PUSH | TCP_FLAGS_ACK);
|
||||||
|
|
||||||
Tip->LoopWait(Callback, this, 3000);
|
//Tip->LoopWait(Callback, this, 3000);
|
||||||
|
|
||||||
if(tcp->Flags & TCP_FLAGS_ACK)
|
bool wait = false;
|
||||||
|
WaitAck = &wait;
|
||||||
|
|
||||||
|
// 等待响应
|
||||||
|
TimeWheel tw(0, 3000);
|
||||||
|
tw.Sleep = 1;
|
||||||
|
do{
|
||||||
|
if(wait) break;
|
||||||
|
}while(!tw.Expired());
|
||||||
|
|
||||||
|
WaitAck = NULL;
|
||||||
|
|
||||||
|
if(wait)
|
||||||
debug_printf("发送成功!\r\n");
|
debug_printf("发送成功!\r\n");
|
||||||
else
|
else
|
||||||
debug_printf("发送失败!\r\n");
|
debug_printf("发送失败!\r\n");
|
||||||
|
@ -425,9 +444,22 @@ bool TcpSocket::Connect(IPAddress& ip, ushort port)
|
||||||
Status = SynSent;
|
Status = SynSent;
|
||||||
Send(*tcp, 0, TCP_FLAGS_SYN);
|
Send(*tcp, 0, TCP_FLAGS_SYN);
|
||||||
|
|
||||||
if(Tip->LoopWait(Callback, this, 3000))
|
//if(Tip->LoopWait(Callback, this, 3000))
|
||||||
|
|
||||||
|
bool wait = false;
|
||||||
|
WaitAck = &wait;
|
||||||
|
|
||||||
|
// 等待响应
|
||||||
|
TimeWheel tw(0, 3000);
|
||||||
|
tw.Sleep = 1;
|
||||||
|
do{
|
||||||
|
if(wait) break;
|
||||||
|
}while(!tw.Expired());
|
||||||
|
|
||||||
|
WaitAck = NULL;
|
||||||
|
|
||||||
|
if(wait)
|
||||||
{
|
{
|
||||||
//if(tcp->Flags & TCP_FLAGS_SYN)
|
|
||||||
if(Status == SynAck)
|
if(Status == SynAck)
|
||||||
{
|
{
|
||||||
Status = Established;
|
Status = Established;
|
||||||
|
@ -444,7 +476,7 @@ bool TcpSocket::Connect(IPAddress& ip, ushort port)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Callback(TinyIP* tip, void* param, Stream& ms)
|
/*bool Callback(TinyIP* tip, void* param, Stream& ms)
|
||||||
{
|
{
|
||||||
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
|
ETH_HEADER* eth = ms.Retrieve<ETH_HEADER>();
|
||||||
if(eth->Type != ETH_IP) return false;
|
if(eth->Type != ETH_IP) return false;
|
||||||
|
@ -480,7 +512,7 @@ bool Callback(TinyIP* tip, void* param, Stream& ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
bool TcpSocket::OnWrite(const byte* buf, uint len)
|
bool TcpSocket::OnWrite(const byte* buf, uint len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -180,7 +180,7 @@ void TinyIP::Work(void* param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TinyIP::LoopWait(LoopFilter filter, void* param, uint msTimeout)
|
/*bool TinyIP::LoopWait(LoopFilter filter, void* param, uint msTimeout)
|
||||||
{
|
{
|
||||||
// 分配一个同样大小的缓冲区
|
// 分配一个同样大小的缓冲区
|
||||||
byte buf[ArrayLength(Buffer)];
|
byte buf[ArrayLength(Buffer)];
|
||||||
|
@ -209,7 +209,7 @@ bool TinyIP::LoopWait(LoopFilter filter, void* param, uint msTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
bool TinyIP::Open()
|
bool TinyIP::Open()
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,8 +33,8 @@ public:
|
||||||
Socket* FindByType(ushort type);
|
Socket* FindByType(ushort type);
|
||||||
};
|
};
|
||||||
|
|
||||||
class TinyIP;
|
//class TinyIP;
|
||||||
typedef bool (*LoopFilter)(TinyIP* tip, void* param, Stream& ms);
|
//typedef bool (*LoopFilter)(TinyIP* tip, void* param, Stream& ms);
|
||||||
|
|
||||||
// 精简以太网协议。封装以太网帧以及IP协议,不包含其它协议实现,仅提供底层支持。
|
// 精简以太网协议。封装以太网帧以及IP协议,不包含其它协议实现,仅提供底层支持。
|
||||||
class TinyIP
|
class TinyIP
|
||||||
|
@ -54,7 +54,7 @@ public:
|
||||||
// 任务函数
|
// 任务函数
|
||||||
static void Work(void* param);
|
static void Work(void* param);
|
||||||
// 带过滤器的轮询
|
// 带过滤器的轮询
|
||||||
bool LoopWait(LoopFilter filter, void* param, uint msTimeout);
|
//bool LoopWait(LoopFilter filter, void* param, uint msTimeout);
|
||||||
// 处理数据包
|
// 处理数据包
|
||||||
void Process(Stream& ms);
|
void Process(Stream& ms);
|
||||||
// 修正IP包负载数据的长度。物理层送来的长度可能有误,一般超长
|
// 修正IP包负载数据的长度。物理层送来的长度可能有误,一般超长
|
||||||
|
|
Loading…
Reference in New Issue