IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux:多进程版本的服务端分析与实现 -> 正文阅读

[系统运维]Linux:多进程版本的服务端分析与实现

服务端开发一般流程

一:函数简介

1.1:fork创建子进程

Linux:虚拟地址空间,程序和进程,创建并回收子进程,孤儿进程和僵尸进程。为什么要回收子进程?_来年秋风起^的博客-CSDN博客

这里详细讲述了进程的创建和资源回收,有兴趣的朋友可以去看看。

1.2:socket创建套接字

1.3:setsockopt设置端口复用

1.4:bind绑定端口和IP

其中IP和port为函数传入参数,端口号必须设定一个确定的端口号。?

   17 int Tcp_socket_bind_listen(const char* IP, unsigned short port)
   18 {
   19   int lfd = socket(AF_INET, SOCK_STREAM, 0);
   20   if(lfd < 0)
   21   {
   22     perror_exit("socket error");
   23   }
   24
   25   int opt = 1;
   26   setsockopt(lfd, SO_REUSEADDR, SOL_SOCKET, &opt, sizeof(opt));
   27
   28   struct sockaddr_in serv;
   29   if(IP){
   30     inet_pton(AF_INET, IP, &serv.sin_addr.s_addr);
   31   }else {
   32     serv.sin_addr.s_addr = htonl(INADDR_ANY);
   33   }
   34   serv.sin_port = htons(port);
   35   int ret = bind(lfd, (struct sockaddr*)&serv, sizeof(serv));
   36   if(ret < 0)
   37   {
   38     perror_exit("bind error");
   39   }
   40
   41   listen(lfd, 128); // 设置文件描述符为监听状态
   42
   43   return lfd;
   44 } 

二:设置信号处理函数

2.1:SIGCHLD信号

?SIGCHLD信号,子进程退出时会给父进程发送该信号, 父进程收到该信号后,不管代码执行到那个位置,都会去执行信号处理函数。我们在该信号处理函数中进行对子进程资源的回收。

这里需要注意的是,一定要在创建子进程之前进行信号处理函数的注册。因为在linux操作系统下,进程的执行顺序是随机的,哪个进程抢到cpu的时间片,哪个进程就先执行。这里让父进程在创建子进程前注册信号处理函数,是为了防止在父进程还未执行到注册信号时子进程就已经执行完代码并退出了,这样就会产生僵尸进程。

三:父子进程分工配合实现多进程服务器

父进程负责进行监听,等待客户端链接,拿到与客户端的通信文件描述符,交给子进程进行数据的交换(通信)。

?

这里我只是对客户端发送一个“hello linux”。?

最后附上完整代码:



 12 void perror_exit(const char* str)
 13 {
 14   perror(str);
 15   exit(-1);
 16 }
 17
 18 int Tcp_socket_bind_listen(unsigned short port)
 19 {
 20   // 创建socket套接字 指定网络通信,TCP传输协议
 21   int lfd = socket(AF_INET, SOCK_STREAM, 0);
 22   if(lfd < 0)
 23   {
 24     perror_exit("socket error");
 25   }
 26
 27   // 设置端口复用
 28   int opt = 1;
 29   setsockopt(lfd, SO_REUSEADDR, SOL_SOCKET, &opt, sizeof(opt));
 30
 31   // 绑定lfd与IP和端口
 32   struct sockaddr_in serv;
 33   serv.sin_addr.s_addr = htonl(INADDR_ANY);
 34   serv.sin_port = htons(port);
 35   int ret = bind(lfd, (struct sockaddr*)&serv, sizeof(serv));
 36   if(ret < 0)
 37   {
 38     perror_exit("bind error");
 39   }
 40
 41   // 设置文件描述符为监听状态
 42   listen(lfd, 128);
 43
 44   return lfd;
 45 }
 46
 47 int Accept(int fd)
 48 {
 49   int cfd;
 50   do
 51   {
 52     cfd = accept(fd, NULL, NULL);
 53     if(cfd < 0)
 54     {
 55       if(errno == EINTR)
 56       {
 57         continue;
 58       }
 59       return -1;
 60     }
 61
 62   }while(0);
 63   return cfd;
 64 }
 66 void sighandle(int signo)
 67 {
 68   pid_t pid ;
 69   while(1)
 70   {
 71     pid = waitpid(-1, NULL, WNOHANG);
 72     if(pid > 0)
 73     {
 74       printf("child pid ==[%d] signo == [%d]\n", pid, signo);
 75     }
 76     else
 77     {
 78       break;
 79     }
 80   }
 81 }
 82
 83 int main()
 84 {
 85   // 创建监听文件描述符
 86   int lfd = Tcp_socket_bind_listen(9999);
 87
 88   // 注册信号捕主捉函数
 89   struct sigaction act;
 90   act.sa_flags = 0;
 91   sigemptyset(&act.sa_mask);
 92   act.sa_handler = sighandle;
 93   sigaction(SIGCHLD, &act, NULL);
 94
 95   while(1)
 96   {
 97     int cfd = Accept(lfd);
 98     pid_t pid = fork();
 99     if(pid) // 父进程
100     {
101       close(cfd);
102     }
103
104     if(!pid) // 子进程
105     {
106       write(cfd, "hello linux", 11);
107       close(cfd);
108       break;
109     }
110
111   }
112
113   close(lfd);
114
115   return 0;
116 }


  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 21:17:28  更:2022-10-08 21:18:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:31:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码