本文主要向大家介绍了C/C++知识点之一个epoll事件实现的高并发服务/客户端(C语言实现,服务端存储基于hashtable),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
之前实现了一个简单高效的hashtable(点这里),之后一直想利用它再延伸一些功能,后来偶然看到一个hashtable与epoll事件的结合感觉效率很高所以自己尝试着实现了下。大体思想是将epoll接到的每一个服务请求存储到hashtable里来管理,每一个请求都可以设置独立的回调函数。具体可以先看代码,注释已经写得很详细。代码实现了一个简单实例,由于条件有限,client端我是fork了大量子进程来模仿高并发请求。性能测试我这几天有时间再搞下,大概试了下1s几十万次请求应该是可以的。暂时先写到这里,下面先贴一个client的源码充下大小..
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include "error.h"
14
15
16 /*进程共享文件用于统计创建进程个数*/
17 #define PFILE_NAME "count"
18
19
20 struct shared {
21 sem_t mutex; /*信号量用于加锁*/
22 int count; /*进程个数*/
23 } shared;
24
25
26 void request(const char *server_ip, int server_port)
27 {
28 struct sockaddr_in client_addr;
29 bzero(&client_addr, sizeof(client_addr));
30 client_addr.sin_family = AF_INET;
31 client_addr.sin_addr.s_addr = INADDR_ANY;
32 client_addr.sin_port = htons(0);
33
34 int client_socket = socket(AF_INET, SOCK_STREAM, 0);
35 if(client_socket
36
37 struct sockaddr_in server_addr;
38 bzero((char *)&server_addr, sizeof(server_addr));
39
40 server_addr.sin_family = AF_INET;
41
42 struct hostent *server = gethostbyname(server_ip);
43 if(!server) sys_exit_throw("fail to get host name");
44
45 bcopy((char *)server->h_addr, (char *)&server_addr.sin_addr.s_addr, server->h_length);
46
47 server_addr.sin_port = htons(server_port);
48 socklen_t server_addr_len = sizeof(server_addr);
49
50 if(connect(client_socket, (struct sockaddr*) &server_addr, server_addr_len) == -1 ) {
51 sys_exit_throw("connent to server fail");
52 }
53
54 int pid = getpid();
55
56 char content[64] = {0};
57 sprintf(content, "%s, pid:%d", "i am client!", pid);
58
59 send(client_socket, content, strlen(content), 0);
60
61 close(client_socket);
62 }
63
64 /*
65 参数1为serverip,参数2为server端口号
66 */
67 int main(int argc,char *argv[])
68 {
69 if(argc != 3) exit_throw("parameter error!\n");
70
71 char *server_ip = argv[1];
72 int server_port = atoi(argv[2]);
73
74 struct shared *psh;
75
76 /*创建共享文件*/
77 int fd = open(PFILE_NAME, O_RDWR | O_CREAT, 0666);
78 /*初始化*/
79 write(fd, &shared, sizeof(struct shared));
80 /*映射内存*/
81 psh = mmap(NULL, sizeof(struct shared), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
82 close(fd);
83
84 sem_init(&psh->mutex, 1, 1);
85
86 /*初始进程+1*/
87 psh->count++;
88
89 int i, status;
90 for (i = 0; i
91 pid_t fpid = fork();
92 if (0 == fpid) {
93 sem_wait(&psh->mutex);
94 psh->count++;
95 printf("%d processes have created!\n", psh->count);
96 sem_post(&psh->mutex);
97 request(server_ip, server_port);
98 }
99 else if (fpid > 0) {
100 request(server_ip, server_port);
101 wait(&status);
102 }
103 else
104 sys_exit_throw("fork error!");
105 }
106
107 return 0;
108 }
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!