Skip to content

Commit 8c2a2f2

Browse files
authored
Add C++17 UDPServer ID handling (#260)
1 parent 8df4a64 commit 8c2a2f2

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/Network/UdpServer.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ static UdpServer::PeerIdType makeSockId(sockaddr *addr, int) {
2525
UdpServer::PeerIdType ret;
2626
switch (addr->sa_family) {
2727
case AF_INET : {
28-
ret.resize(18);
2928
ret[0] = ((struct sockaddr_in *) addr)->sin_port >> 8;
3029
ret[1] = ((struct sockaddr_in *) addr)->sin_port & 0xFF;
3130
//ipv4地址统一转换为ipv6方式处理 [AUTO-TRANSLATED:ad7cf8c3]
@@ -35,13 +34,12 @@ static UdpServer::PeerIdType makeSockId(sockaddr *addr, int) {
3534
return ret;
3635
}
3736
case AF_INET6 : {
38-
ret.resize(18);
3937
ret[0] = ((struct sockaddr_in6 *) addr)->sin6_port >> 8;
4038
ret[1] = ((struct sockaddr_in6 *) addr)->sin6_port & 0xFF;
4139
memcpy(&ret[2], &(((struct sockaddr_in6 *)addr)->sin6_addr), 16);
4240
return ret;
4341
}
44-
default: assert(0); return "";
42+
default: throw std::invalid_argument("invalid sockaddr address");
4543
}
4644
}
4745

@@ -78,7 +76,7 @@ void UdpServer::start_l(uint16_t port, const std::string &host) {
7876
//主server才创建session map,其他cloned server共享之 [AUTO-TRANSLATED:113cf4fd]
7977
//Only the main server creates a session map, other cloned servers share it
8078
_session_mutex = std::make_shared<std::recursive_mutex>();
81-
_session_map = std::make_shared<std::unordered_map<PeerIdType, SessionHelper::Ptr> >();
79+
_session_map = std::make_shared<SessionMapType>();
8280

8381
// 新建一个定时器定时管理这些 udp 会话,这些对象只由主server做超时管理,cloned server不管理 [AUTO-TRANSLATED:d20478a2]
8482
//Create a timer to manage these udp sessions periodically, these objects are only managed by the main server, cloned servers do not manage them
@@ -207,7 +205,7 @@ void UdpServer::onManagerSession() {
207205
std::lock_guard<std::recursive_mutex> lock(*_session_mutex);
208206
//拷贝map,防止遍历时移除对象 [AUTO-TRANSLATED:ebbc7595]
209207
//Copy the map to prevent objects from being removed during traversal
210-
copy_map = std::make_shared<std::unordered_map<PeerIdType, SessionHelper::Ptr> >(*_session_map);
208+
copy_map = std::make_shared<SessionMapType>(*_session_map);
211209
}
212210
auto lam = [copy_map]() {
213211
for (auto &pr : *copy_map) {

src/Network/UdpServer.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,42 @@
1111
#ifndef TOOLKIT_NETWORK_UDPSERVER_H
1212
#define TOOLKIT_NETWORK_UDPSERVER_H
1313

14+
#if __cplusplus >= 201703L
15+
#include <array>
16+
#include <string_view>
17+
#endif
1418
#include "Server.h"
1519
#include "Session.h"
1620

1721
namespace toolkit {
1822

1923
class UdpServer : public Server {
2024
public:
25+
#if __cplusplus >= 201703L
26+
class PeerIdType : public std::array<char, 18> {
27+
#else
28+
class PeerIdType : public std::string {
29+
#endif
30+
public:
31+
#if __cplusplus < 201703L
32+
PeerIdType() {
33+
resize(18);
34+
}
35+
#endif
36+
bool operator==(const PeerIdType &that) const {
37+
return as<uint64_t>(0) == that.as<uint64_t>(0) &&
38+
as<uint64_t>(8) == that.as<uint64_t>(8) &&
39+
as<uint16_t>(16) == that.as<uint16_t>(16);
40+
}
41+
42+
private:
43+
template <class T>
44+
const T& as(size_t offset) const {
45+
return *(reinterpret_cast<const T *>(data() + offset));
46+
}
47+
};
48+
2149
using Ptr = std::shared_ptr<UdpServer>;
22-
using PeerIdType = std::string;
2350
using onCreateSocket = std::function<Socket::Ptr(const EventPoller::Ptr &, const Buffer::Ptr &, struct sockaddr *, int)>;
2451

2552
explicit UdpServer(const EventPoller::Ptr &poller = nullptr);
@@ -75,6 +102,15 @@ class UdpServer : public Server {
75102
virtual void cloneFrom(const UdpServer &that);
76103

77104
private:
105+
struct PeerIdHash {
106+
#if __cplusplus >= 201703L
107+
size_t operator()(const PeerIdType &v) const noexcept { return std::hash<std::string_view> {}(std::string_view(v.data(), v.size())); }
108+
#else
109+
size_t operator()(const PeerIdType &v) const noexcept { return std::hash<std::string> {}(v); }
110+
#endif
111+
};
112+
using SessionMapType = std::unordered_map<PeerIdType, SessionHelper::Ptr, PeerIdHash>;
113+
78114
/**
79115
* @brief 开始udp server
80116
* @param port 本机端口,0则随机
@@ -150,7 +186,7 @@ class UdpServer : public Server {
150186
//cloned server共享主server的session map,防止数据在不同server间漂移 [AUTO-TRANSLATED:9a149e52]
151187
//Cloned server shares the session map with the main server, preventing data drift between different servers
152188
std::shared_ptr<std::recursive_mutex> _session_mutex;
153-
std::shared_ptr<std::unordered_map<PeerIdType, SessionHelper::Ptr> > _session_map;
189+
std::shared_ptr<SessionMapType> _session_map;
154190
//主server持有cloned server的引用 [AUTO-TRANSLATED:04a6403a]
155191
//Main server holds a reference to the cloned server
156192
std::unordered_map<EventPoller *, Ptr> _cloned_server;

0 commit comments

Comments
 (0)