多进程TCP并发服务器

多进程TCP并发服务器

最初的服务器都是迭代服务器,服务器处理完一个客户的请求,再接受下一个客户的请求。但是我们的期望应该是一台服务器同时为多个客户服务。实现并发服务器最简单的办法就是为每个客户均fork一个子进程。

基本思路

基本流程是,建立连接,accept返回后,服务器调用fork,子进程通过已连接套接口(connfd)为客户提供服务,父进程通过监听套接口(listenfd)等待另一个连接。子进程开始处理客户后,父进程便关闭已连接套接口。

...
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
listen(listenfd, LISTENQ);
for ( ; ; ) {
    connfd = accept(listenfd, (SA *) &cliaddr, &clilen));
    if ( (childpid = Fork()) == 0) { /* 子进程 */
        close(listenfd);    /* 子进程关闭监听套接口 */
        doit(connfd);       /* 子进程通过已连接套接口处理请求 */
        close(connfd);      /* 子进程处理请求完毕,关闭已连接套接口
                            /* 这一步可省略,因为exit会关闭所有由内核打开的描述字 */
        exit(0);            /* 子进程结束 */
    }
    close(connfd);          /* 父进程关闭已连接套接口 */
}

描述字访问计数

对TCP套接口调用close会引发FIN,终止连接。但是上面父进程的Close(connfd)却并没有影响子进程使用这个描述字进行客户请求处理,这是因为,父进程调用close只是将它的文件表项访问计数减一,文件表项访问计数值为0时才真正关闭。

  1. accept返回,connfd计数=1
  2. fork返回,connfd计数=2
  3. 父进程closeconnfd计数=1
  4. 子进程closeconnfd计数=0,引发FIN,终止连接

分步骤状态图解

下图是服务器阻塞于accept调用、连接请求从客户到达时客户和服务器的状态。

accept返回前客户-服务器的状态

accept返回后,就有下图的状态。连接被内核接受,新的套接口即connfd被创建,这个已连接套接口,可用来读写数据。

accept返回后客户-服务器的状态

并发服务器的下一步是调用fork,下图是从fork返回后的状态。此时描述字listenfdconnfd是父进程-子进程共享的。

fork返回后客户-服务器的状态

下一步是父进程关闭已连接套接口,子进程关闭监听套接口。

父子进程关闭相应套接口后客户-服务器的状态

最后的结果是子进程处理与客户的连接,父进程可对监听套接口调用accept来处理下一个连接。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Linyb极客之路

linux常用基本命令之文件搜索命令

命令:find 语法:find [搜索范围路径] -name 【文件名称】(根据文件名查找) find [搜索范围路径] -size [...

4016
来自专栏拂晓风起

cocos2d-js 3.0 rc0 编译release报错 value for keystore is not valid. it must resolve to a single path

1172
来自专栏专注数据中心高性能网络技术研发

如何解压RPM包

Mellanox的驱动源码在centos7下面是使用RPM包封装的,需要解压此格式的包来获取源文件 RPM包括是使用cpio格式打包的,因此可以先转成cpio然...

6715
来自专栏快乐八哥

MongoDB学习系列(2)--使用PHP访问MongoDB

第一部分:介绍 在Windows上安装最新MongoDB步骤非常的简单,这里不做介绍。但是如果你安装的时候没有将MongoDB作为服务运行,每次你都要使用cmd...

2496
来自专栏Vamei实验室

Linux常用命令

我总结了常用的Linux命令,方便你的Linux使用。下面是格式说明,你现在可以跳过,直到遇到疑问时再来查询。 $ 命令行提示符 粗体表示命令 斜体表示参数 ...

3337
来自专栏开源优测

AutoLine源码分析之入口源码

AutoLine开源平台是一个开源自动化测试解决方案,基于RobotFramework进行二次开发,支持RobotFramework几乎所有的库。

1233
来自专栏Java架构

Java 程序员须知道和掌握的 Linux 命令

1883
来自专栏小樱的经验随笔

【批处理学习笔记】第十二课:常用DOS命令(2)

 文件管理 type 显示文本文件的内容。 copy 将一份或多份文件复制到另一个位置。 del 删除一个或数个文件。 move 移动文件并重命名文件和目录。(...

2904
来自专栏技术博文

linux最常用的20条命令

玩过Linux的人都会知道,Linux中的命令的确是非常多,但是玩过Linux的人也从来不会因为Linux的命令如此之多而烦恼,因为我们只需要掌握我们最常用的命...

3434
来自专栏Python小屋

Python操作Excel文件中多WorkSheet模拟数据库内连接查询

严格意义上来讲,是可以把Excel文件看作数据库的,C#通过OLEDB.net就可以使用SQL语句操作Excel文件中的数据。 本文代码使用Python扩展库o...

3514

扫码关注云+社区

领取腾讯云代金券