多进程以及多线程socket编程
来源:互联网 发布:美浓烧底标 知乎 编辑:程序博客网 时间:2024/06/04 17:51
在我的上篇博客中已经详细介绍了socket编程中所需要的函数,在这里就不过多介绍了,有需要的话可以参考上一篇博客:http://blog.csdn.net/qq_36221862/article/details/73611942
多进程,多线程socket编程与单进程不同的只是服务器端的不同,客户端是一样的。
多进程:父进程fork子进程, 子进程退出,但是子进程的子进程仍在运行,变成了孤儿进程,由1号进程回收,父进程不用等待子进程的子进程的退出,它俩是爷孙进程,不用回收子进程。
pid_t id = fork(); if(id < 0) { close(new_sock); } else if(id == 0) //子进程 { close(listen_sock); //关闭不必要的文件描述局,不关闭的话,文教描述符表会越来越少,造成资源的浪费 if(fork() > 0) { exit(1); } else if(id == 0) { //服务客户端 } else { close(new_sock); } else { close(new_sock); }
多进程socket编程服务器端代码:
#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <errno.h>#include <arpa/inet.h>#include <string.h>#include <stdlib.h>static void usage(const char* proc) //使用说明{ printf("Usage:%s [local_ip] [local_port]\n", proc);}int startup(const char* _ip, int _port) //创建套接字{ // int sock = socket(AF_INET, SOCK_STREAM , 0);// if(sock < 0)/// { // perror("socket\n");// exit(2);// } **struct sockaddr_in local; int reuse = 0; struct sockaddr_in cliaddr, servaddr; int sock = socket(PF_INET, SOCK_STREAM,0); if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { perror("setsockopet error\n"); return -1; }** //避免绑定失败,在上篇博客也已经解释过了 local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip); if(bind(sock, (struct sockaddr*)&local, sizeof(local))<0) { perror("bind\n"); exit(3); } if(listen(sock, 10) < 0) { perror("listen\n"); exit(4); } return sock;}//tcp_server 127.0.0.1 8080int main(int argc, char* argv[]){ if(argc != 3) { usage(argv[0]); return 1; } int listen_sock = startup(argv[1], atoi(argv[2])); //监听状态 struct sockaddr_in client; socklen_t len = sizeof(client);struct sockaddr_in cliaddr, servaddr; while(1) { int new_sock = accept(listen_sock, (struct sockaddr*)&client, &len); if(new_sock < 0) { perror("accept\n"); continue; //继续监听,直到有新客户到来 } //获取新客户 printf("get a new client,%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); //服务新客户 pid_t id = fork(); if(id < 0) { close(new_sock); } else if(id == 0) //子进程 { close(listen_sock); if(fork() > 0) { exit(1); } else if(id == 0) { while(1) { char buf[1024000]; //服务器端先读再写 ssize_t s = read(new_sock, buf, sizeof(buf)-1); if(s > 0) { buf[s] = 0; printf("client: %s\n", buf); write(new_sock, buf, strlen(buf)); } else if(s == 0) { close(new_sock); printf("client is quit...\n"); break; } else { perror("read\n"); close(new_sock); exit(5); } } } close(new_sock); } else { close(new_sock); } break; }}
多线程:不用关闭多余的文件描述符表,进程有两张文件描述符表,而线程只有一张文件描述符表,共享进程的文件描述符表,因此不用关闭多余的文件描述符表。
查看一个进程有多少个线程:
pthread_t id; pthread_create(&id, NULL, handlerRequest, (void*)new_sock); //创建线程 pthread_detach(id); //线程分离
多线程socket编程源代码:
#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <errno.h>#include <arpa/inet.h>#include <string.h>-#include <stdlib.h>static void usage(const char* proc) //使用说明{ printf("Usage:%s [local_ip] [local_port]\n", proc);——}int startup(const char* _ip, int _port) //创建套接字{ int sock = socket(AF_INET, SOCK_STREAM , 0); if(sock < 0) { perror("socket\n"); exit(2); } struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip); if(bind(sock, (struct sockaddr*)&local, sizeof(local))<0) { perror("bind\n"); exit(3); } if(listen(sock, 10) < 0) { perror("listen\n"); exit(4); } return sock;}void handlerRequest(void* arg){ int new_sock = (int)arg; while(1) { char buf[1024]; //服务器端先读再写 ssize_t s = read(new_sock, buf, sizeof(buf)-1); if(s > 0) { buf[s] = 0; printf("client: %s\n", buf); write(new_sock, buf, strlen(buf)); } else if(s == 0) { close(new_sock); printf("client is quit...\n"); break; } else { perror("read\n"); close(new_sock); exit(5); } }}//tcp_server 127.0.0.1 8080int main(int argc, char* argv[]){ if(argc != 3) { usage(argv[0]); return 1; } int listen_sock = startup(argv[1], atoi(argv[2])); //监听状态 struct sockaddr_in client; socklen_t len = sizeof(client); while(1) { int new_sock = accept(listen_sock, (struct sockaddr*)&client, &len); if(new_sock < 0) { perror("accept\n"); continue; //继续监听,直到有新客户到来 } //获取新客户 printf("get a new client,%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); //服务新客户 pthread_t id; pthread_create(&id, NULL, handlerRequest, (void*)new_sock); pthread_detach(id); //线程分离 }}
阅读全文
0 0
- 多进程以及多线程socket编程
- 2016-3-10 UNIX 多进程多线程socket编程
- Java的Socket网络编程以及多线程
- socket--多进程,多线程服务器
- 多进程socket编程示例
- 【linux】多进程、多线程编程
- 多进程和多线程编程
- 多进程和多线程编程
- 多进程和多线程编程
- python 多进程 多线程编程
- java网络编程(二)复用Socket连接以及使用多线程完成多个客户端的连接
- MFC多进程多线程编程之--多线程
- gdb如何调试多线程以及多进程
- 多进程、多线程以及如何选择?
- PHP多进程协作编程之-socket
- Socket通信中的多进程编程实例
- Socket通信中的多进程编程实例
- Socket通信中的多进程编程实例
- laravel构造函数和中间件执行顺序问题
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- BT 运行及内网穿透原理
- spring-boot 入门 ssmb小例子
- 算法
- 多进程以及多线程socket编程
- UEFI在高通平台实现
- Group Anagrams
- 判断用户当前使用的终端
- java.io.File类分析
- Jenkins+Maven+TestNG集成+ HTML测试结果+测试重跑机制
- yii框架的增删改查
- Django自定义http header
- node.js 乱码问题