在写网络程序或者做端口映射工具时,经常会遇到一堆连接请求要处理。怎么把这些连接信息存好、找快、删干净?光靠几个变量可搞不定,得靠数据结构撑场面。而用C++来实现这些结构,既灵活又高效。
链表:动态管理连接节点
比如你写了个端口转发服务,每个新进来的TCP连接都要记录IP、端口、状态。用数组?长度固定太麻烦。这时候链表就派上用场了。每个连接封装成一个节点,随时插入删除。
struct ConnectionNode {
std::string ip;
int port;
int status;
ConnectionNode* next;
ConnectionNode(std::string i, int p) : ip(i), port(p), status(1), next(nullptr) {}
};
class ConnectionList {
private:
ConnectionNode* head;
public:
ConnectionList() : head(nullptr) {}
void addConnection(std::string ip, int port) {
ConnectionNode* node = new ConnectionNode(ip, port);
node->next = head;
head = node;
}
};
每次有新连接进来,调一下addConnection,干净利落。内存动态分配,不浪费。
栈:处理嵌套配置项
端口映射规则有时候是嵌套的,比如某条规则依赖前置条件。解析配置文件时,可以用栈来追踪层级。读到一个开启标签就压栈,关闭就弹出。
#include <stack>
#include <string>
std::stack<std::string> ruleStack;
void enterRule(std::string name) {
ruleStack.push(name);
std::cout << "Entering rule: " << name << std::endl;
}
void exitRule() {
if (!ruleStack.empty()) {
std::cout << "Exiting rule: " << ruleStack.top() << std::endl;
ruleStack.pop();
}
}
哈希表:快速查找端口映射关系
最常用的就是从外部端口快速找到内部服务地址。map或unordered_map直接搞定。
#include <unordered_map>
std::unordered_map<int, std::pair<std::string, int>> portMap;
// 外部端口 -> (内网IP, 内网端口)
void setupMapping(int externalPort, std::string internalIp, int internalPort) {
portMap[externalPort] = std::make_pair(internalIp, internalPort);
}
std::pair<std::string, int> getInternalTarget(int externalPort) {
return portMap.find(externalPort) != portMap.end() ?
portMap[externalPort] : std::make_pair(std::string("0.0.0.0"), 0);
}
查个映射关系,O(1)时间搞定,比遍历快多了。
队列:处理连接请求的顺序调度
当多个设备同时请求同一个映射端口时,总得排个队。先进先出用queue最合适。
#include <queue>
std::queue<std::string> requestQueue;
void enqueueRequest(std::string client) {
requestQueue.push(client);
}
void processNext() {
if (!requestQueue.empty()) {
std::cout << "Processing: " << requestQueue.front() << std::endl;
requestQueue.pop();
}
}
这样不会漏掉任何一个请求,也不会让某个客户端一直卡着不动。
数据结构不是课本里的摆设,它是你写实用程序时的工具箱。用C++实现起来,类封装+STL配合,既清晰又高效。下次写映射逻辑时,不妨想想该用哪个结构来理清数据。”}