unix/linux 系统实现多个进程监听同一个端口
2017-03-20 21:10
543 查看
转自:http://blog.csdn.net/youjun9007228198/article/details/19946129
一直疑惑一个应用app如何才能以多进程,多线程的方式运行。对于多线程可能很好理解,我们只要在进程中启用多线程的模式即可。也就是来一个请求,我们就用函数pthread_create()启用一个线程即可。这样我们的应用就可以在单进程,多线程的模式下工作。
但我们知道一个应用app通常工作在多进程,多线程的模式下,它的效率是最高的。那么我们如何才能做到多进程模式呢?经验告诉我们,如果多次启动一个进程会报错:“Address already in use!"。这是由于bind函数导致的,由于该端口号已经被监听了。
其实我们只要在绑定端口号(bind函数)之后,监听端口号之前(listen函数),用fork()函数生成子进程,这样子进程就可以克隆父进程,达到监听同一个端口的目的。好了,废话不多说,我们看一下具体代码。
来自CODE的代码片
serv.c
接下来我们来启动一下,查看结果如下:
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 500 3019 2370 0 80 0 - 1315 - tty2 00:00:01 bash
0 S 500 7332 3019 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7333 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7334 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7335 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7336 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7337 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7338 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
我们可以看到,确实有多个服务(multi_proc)成功起来了,那么这些进程是否能够监听9988这个端口,并且产生竞争呢?我们来写一段客户端的代码做个测试。客户端主要是循环多次请求服务器,并发送字符串。
来自CODE的代码片
clnt.c
请求执行后,我们看一下,服务器打印的结果!
pid=7738, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7732, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7738, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7732, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7738, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7732, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7738, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7738, mesg: Hello Server!
我们可以看出,这些进程都能监听同一个接口,而且还相互竞争,提高程序效率!
一直疑惑一个应用app如何才能以多进程,多线程的方式运行。对于多线程可能很好理解,我们只要在进程中启用多线程的模式即可。也就是来一个请求,我们就用函数pthread_create()启用一个线程即可。这样我们的应用就可以在单进程,多线程的模式下工作。
但我们知道一个应用app通常工作在多进程,多线程的模式下,它的效率是最高的。那么我们如何才能做到多进程模式呢?经验告诉我们,如果多次启动一个进程会报错:“Address already in use!"。这是由于bind函数导致的,由于该端口号已经被监听了。
其实我们只要在绑定端口号(bind函数)之后,监听端口号之前(listen函数),用fork()函数生成子进程,这样子进程就可以克隆父进程,达到监听同一个端口的目的。好了,废话不多说,我们看一下具体代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<unistd.h> #define oops(m) {perror(m); exit(1);}int main(){ int sock_id; struct sockaddr_in saddr; sock_id = socket(PF_INET, SOCK_STREAM, 0); saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); saddr.sin_port = htons(9988); saddr.sin_family = AF_INET; int ret = bind(sock_id, (struct sockaddr *) &saddr, sizeof(saddr));//绑定IP地址和端口 if(ret == -1) oops("bind error");//如果返回-1,则绑定失败,一般为“Address alreay in use” int i; for(i = 0; i < 6; i++){//连续创建六个子进程 int pid = fork(); if(pid == 0) break; } listen(sock_id, 1); while(1){ int sock = accept(sock_id, NULL, 0); char buf[128]; int readnum; readnum = read(sock, buf, 127); buf[readnum] = '\0'; printf("pid=%d, mesg: %s\n", getpid(), buf); fflush(stdout); close(sock); } return 1;} |
来自CODE的代码片
serv.c
接下来我们来启动一下,查看结果如下:
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 500 3019 2370 0 80 0 - 1315 - tty2 00:00:01 bash
0 S 500 7332 3019 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7333 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7334 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7335 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7336 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7337 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
1 S 500 7338 7332 0 80 0 - 466 - tty2 00:00:00 multi_proc
我们可以看到,确实有多个服务(multi_proc)成功起来了,那么这些进程是否能够监听9988这个端口,并且产生竞争呢?我们来写一段客户端的代码做个测试。客户端主要是循环多次请求服务器,并发送字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<unistd.h>#include<netinet/in.h> int main(){ int i=0; struct sockaddr_in saddr; saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); saddr.sin_port = htons(9988); saddr.sin_family = AF_INET; int addlen = sizeof(saddr); for(; i < 30; i++){ int sock=socket(AF_INET, SOCK_STREAM, 0); connect(sock, (struct sockaddr *) &saddr, addlen); write(sock, "Hello Server!", 13); }} |
来自CODE的代码片
clnt.c
请求执行后,我们看一下,服务器打印的结果!
pid=7738, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7732, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7738, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7732, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7738, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7736, mesg: Hello Server!
pid=7735, mesg: Hello Server!
pid=7734, mesg: Hello Server!
pid=7732, mesg: Hello Server!
pid=7733, mesg: Hello Server!
pid=7738, mesg: Hello Server!
pid=7737, mesg: Hello Server!
pid=7738, mesg: Hello Server!
我们可以看出,这些进程都能监听同一个接口,而且还相互竞争,提高程序效率!
相关文章推荐
- unix/linux 系统实现多个进程监听同一个端口
- linux 系统实现多个进程监听同一个端口(会有惊群)
- Linux 查看 系统正在监听的端口的进程
- 在Linux和Window下如何查看一个端口是否监听以及被哪个进程监听命令
- 一个进程安全的日志类, Linux实现
- Vista系统下IE8有N个进程只显示一个的实现方法
- 实现了一个linux,unix, BSD 上编程工具链
- Linux\Unix IPC进程通信实例分析(一):共享内存通信---系统V
- Unix/Linux如何创建一个后台进程(run background process)
- linux下通过字符模块实现类似ps命令的查看系统进程方法
- linux下查看监听端口对应的进程
- linux下查看监听端口对应的进程
- linux下查看监听端口对应的进程
- linux下单例进程的一个实现方式
- 利用nagios,snmp,监听处理linux下的特定进程和端口,以及邮件短信报警功能 推荐
- 一个嵌入式Linux系统的键盘驱动实现
- linux下如何自动检测并重新启动一个死掉的进程(shell脚本实现)
- linux下单例进程的一个实现方式
- 一个资源管理系统的设计--解析linux的cgroup实现
- 在linux环境中,通过监听端口查找进程号命令