如果每次都要通过循环查找匹配的主机和端口,效率确实会比较低,尤其是在主机和端口数量较多的情况下。
为了避免每次调用时都进行循环查找,可以使用一种更高效的数据结构来存储主机和端口的映射关系,比如 哈希表 或 多级映射。
以下是一个优化方案,使用 哈希表 或 多级映射 来避免循环查找:
优化方案:使用哈希表或多级映射
1. 使用哈希表
哈希表可以快速根据键值对查找对应的回调函数,避免了循环查找的开销。
2. 使用多级映射
如果主机数量较少,但端口数量较多,可以使用多级映射:第一级映射主机,第二级映射端口。
示例代码:使用多级映射
#include <stdio.h>
#include <string.h>
#include <stdlib.h>#define MAX_HOSTS 1
#define MAX_PORTS 4
#define MAX_HOST_LEN 16// 回调函数类型
typedef void (*tcpclientCallback)(void* clientinfo);// 定义回调函数
void tcpclient_port0_callback(void* clientinfo) {printf("Callback for port 5001\n");
}void tcpclient_port1_callback(void* clientinfo) {printf("Callback for port 5002\n");
}void tcpclient_port2_callback(void* clientinfo) {printf("Callback for port 5003\n");
}void tcpclient_port3_callback(void* clientinfo) {printf("Callback for port 5004\n");
}// 多级映射结构
typedef struct {char host[MAX_HOST_LEN];tcpclientCallback port_callbacks[MAX_PORTS];
} HostCallbackMap;// 客户端信息结构
typedef struct {char hosts[MAX_HOST_LEN];int port;char tcp_client_recv_buf[MAX_HOST_LEN];
} ClientInfo;// 初始化多级映射
HostCallbackMap host_map[MAX_HOSTS] = {{"192.168.1.201", {tcpclient_port0_callback, tcpclient_port1_callback, tcpclient_port2_callback, tcpclient_port3_callback}}
};// 处理客户端请求
void handleClient(ClientInfo* asclientinfo) {for (int i = 0; i < MAX_HOSTS; i++) {if (strcmp(asclientinfo->hosts, host_map[i].host) == 0) {// 找到匹配的主机for (int j = 0; j < MAX_PORTS; j++) {if (asclientinfo->port == 5001 + j) { // 假设端口是连续的host_map[i].port_callbacks[j](asclientinfo);return;}}}}printf("No matching host or port found.\n");
}int main() {// 示例客户端信息ClientInfo client = {"192.168.1.201", 5002, "Hello, Server!"};handleClient(&client);return 0;
}
优化后的代码特点
- 多级映射:通过
HostCallbackMap
结构,将主机和端口的回调函数组织起来。 - 减少循环次数:虽然仍然有循环,但循环次数大大减少,且逻辑更加清晰。
- 扩展性:如果需要增加更多主机或端口,只需修改
MAX_HOSTS
和MAX_PORTS
,并更新host_map
数组。
进一步优化:使用哈希表
如果主机数量较多,可以使用哈希表来进一步优化。C语言标准库中没有直接支持哈希表,但可以使用第三方库(如 uthash
)或自己实现一个简单的哈希表。
使用哈希表的示例(基于 uthash
)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uthash.h"#define MAX_PORTS 4typedef void (*tcpclientCallback)(void* clientinfo);typedef struct {char host[MAX_HOST_LEN];tcpclientCallback port_callbacks[MAX_PORTS];UT_hash_handle hh;
} HostCallbackMap;// 回调函数
void tcpclient_port0_callback(void* clientinfo) {printf("Callback for port 5001\n");
}void tcpclient_port1_callback(void* clientinfo) {printf("Callback for port 5002\n");
}void tcpclient_port2_callback(void* clientinfo) {printf("Callback for port 5003\n");
}void tcpclient_port3_callback(void* clientinfo) {printf("Callback for port 5004\n");
}// 客户端信息结构
typedef struct {char hosts[MAX_HOST_LEN];int port;char tcp_client_recv_buf[MAX_HOST_LEN];
} ClientInfo;// 哈希表
HostCallbackMap* host_map = NULL;void addHost(const char* host, tcpclientCallback* callbacks) {HostCallbackMap* entry = (HostCallbackMap*)malloc(sizeof(HostCallbackMap));strcpy(entry->host, host);memcpy(entry->port_callbacks, callbacks, sizeof(entry->port_callbacks));HASH_ADD_STR(host_map, host, entry);
}void handleClient(ClientInfo* asclientinfo) {HostCallbackMap* entry;HASH_FIND_STR(host_map, asclientinfo->hosts, entry);if (entry) {int port_index = asclientinfo->port - 5001;if (port_index >= 0 && port_index < MAX_PORTS) {entry->port_callbacks[port_index](asclientinfo);return;}}printf("No matching host or port found.\n");
}int main() {// 初始化哈希表tcpclientCallback callbacks[MAX_PORTS] = {tcpclient_port0_callback, tcpclient_port1_callback, tcpclient_port2_callback, tcpclient_port3_callback};addHost("192.168.1.201", callbacks);// 示例客户端信息ClientInfo client = {"192.168.1.201", 5002, "Hello, Server!"};handleClient(&client);// 清理哈希表HostCallbackMap* current, *tmp;HASH_ITER(hh, host_map, current, tmp) {HASH_DEL(host_map, current);free(current);}return 0;
}
哈希表的优点
- 快速查找:哈希表的查找时间复杂度为 O(1),大大提高了效率。
- 动态扩展:可以动态添加新的主机和端口映射,而不需要修改数组大小。
通过使用哈希表或多级映射,可以避免每次调用时的循环查找,从而提高代码的效率和可维护性。