今天看linux C 编程实战的my_server例子时,敲到这段代码,对其父子进程关闭socket 进行close调用产生疑问

如图中标注的三个close socket,思考子进程通信结束 关闭自己的通信socket:conn_fd可以理解,但将sock_fd,服务器的监听socket也关闭就不知怎么回事了。而且父进程执行close(conn_fd)将子进程的通信socket关闭,这样不久让子进程无法和客户端soket通信了吗? 但是程序正常运行。重新查资料发现是自己对子进程资源的复制和close函数,还有文件描述符的理解不到位

1. 首先,socket是一种特殊的数据传输IO,也是一种文件描述符。

2. fork创建进程时,子进程共享父进程打开的文件描述符,但父进程对文件描述符的改变不会影响子进程中的文件描述符。

3. close 一个套接字的默认行为是把套接字标记为已关闭,然后立即返回到调用进程,该套接字描述符不能再由调用进程使用,也就是说它不能再作为read或write的第一个参数,然而TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。

  在多进程并发服务器中,父子进程共享着套接字,套接字描述符引用计数记录着共享着的进程个数,当父进程或某一子进程close掉套接字时,描述符引用计数会相应的减一,当引用计数仍大于零时,这个close调用就不会引发TCP的四路握手断连过程。

所以:父进程close(conn_fd)不会对子进程通信造成影响。相反,如果不这么做,在父进程中conn_fd占用着可用的文件描述符,会影响父进程accept链接的个数,因为conn_fd是有用户级限制的(内核为了不让某一个进程消耗掉所有的文件资源,其也会对单个进程最大打开文件数做默认值处理,默认值一般是1024,使用ulimit -n命令可以查看),再accept一个新的连接时,前一个conn_fd被覆盖,就找不到了,但相应的描述符值还是被标记为“占用”,当达到用户级限制时,不可再accept新连接,成为瓶颈。

在Web服务器中,通过更改系统默认值文件描述符的最大值来优化服务器是最常见的方式之一。具体优化方式请查看http://blog.csdn.net/kumu_linux/article/details/7877770 其中介绍的很详细

经本人亲测,如果去除了父进程的close(conn_fd),可以accept的连接数大大减少。而且通过修改系统文件描述符最大值,可以大大提高accept连接数量。

初学Linux 对其中很多细节还不清楚,后续会针对修改!

文件描述符讲解很好的博客:http://blog.csdn.net/cywosp/article/details/38965239

while() {
conn_fd = accept(sock_fd, (struct sockaddr *)&cli_addr, &cli_len);
if (conn_fd < ) {
my_err("accept", __LINE__);
}
printf("accept a new client, ip:%s\n", inet_ntoa(cli_addr.sin_addr));
if ((pid = fork()) == ) {
while() {
if ((ret = recv(conn_fd, recv_buf, sizeof(recv_buf), )) < ) {
perror("recv");
exit();
}
recv_buf[ret-] = '\0';
if (flag_recv == USERNAME) {
name_num = find_name(recv_buf);
switch(name_num) {
case -:
send_data(conn_fd, "n\n");
break;
case -:
exit();
break;
default:
send_data(conn_fd, "y\n");
flag_recv = PASSWORD;
break;
}
}
else if (flag_recv == PASSWORD) {
if (strcmp(users[name_num].password, recv_buf) == ) {
send_data(conn_fd, "y\n");
send_data(conn_fd, "welcome login my tcp server\n");
printf("%s login\n", users[name_num].username);
flag_recv = MESSAGE;
}
else {
send_data(conn_fd, "n\n");
}
}
else if (flag_recv == MESSAGE) {
if (strcmp("quit", recv_buf) == ) {
break;
}
printf("message from %s: %s\n", users[name_num].username, recv_buf);
}
}
close(sock_fd);
close(conn_fd);
printf("child exit!\n");
exit();
}else {
close(conn_fd); }

linuxC编程实战 my_server.c例子问题总结的更多相关文章

  1. 【Java并发编程实战】-----“J.U.C”:Exchanger

    前面介绍了三个同步辅助类:CyclicBarrier.Barrier.Phaser,这篇博客介绍最后一个:Exchanger.JDK API是这样介绍的:可以在对中对元素进行配对和交换的线程的同步点. ...

  2. 【Java并发编程实战】-----synchronized

    在我们的实际应用当中可能经常会遇到这样一个场景:多个线程读或者.写相同的数据,访问相同的文件等等.对于这种情况如果我们不加以控制,是非常容易导致错误的.在java中,为了解决这个问题,引入临界区概念. ...

  3. 在 Boolan 网开讲《网络编程实战》课程

    <网络编程实战>是一门以讲解实例为主的课程,每一节都讲一两个网络编程的例子程序,课程偏重 Linux 服务端 TCP 网络编程. 本课程要求听课人员已经读过<Unix 网络编程> ...

  4. Linux下的C编程实战

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来, Linu ...

  5. Shell高级编程视频教程-跟着老男孩一步步学习Shell高级编程实战视频教程

    Shell高级编程视频教程-跟着老男孩一步步学习Shell高级编程实战视频教程 教程简介: 本教程共71节,主要介绍了shell的相关知识教程,如shell编程需要的基础知识储备.shell脚本概念介 ...

  6. Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  7. 跟着老男孩一步步学习Shell高级编程实战

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://oldboy.blog.51cto.com/2561410/1264627 本sh ...

  8. Linux下的编程实战【转】

    一篇比较不错的文章, 降到了 makefile make , gcc编译器,GDB调试器, Linux文件系统,Linux文件API,.C语言库函数(C库函数的文件操作实际上是独立于具体的操作系统平台 ...

  9. 《Go并发编程实战》读书笔记-语法概览

    <Go并发编程实战>读书笔记-语法概览 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客我们会快速浏览一下Go的语法,内容涉及基本构成要素(比如标识符,关键字,子 ...

随机推荐

  1. MT9M021/MT9M031总结

    MT9M021/MT9m031在低光照度下和捕捉移动场景有非常优异的表现,属于近红外摄像头, S1: Aptina's MT9M021/MT9M031 sensor is capable of a m ...

  2. octopress的一些总结

    1.编辑_config.yml 的description时,不能使用tab键 2.修改主题‘MediumFox’  description 和 文章展示的宽度,修改文件home_landing_row ...

  3. mysql 主从同步配置

    1  环境 mac air 主机做 主库,使用的是XAMPP自带的mysql 版本为 5.6.21, for osx10.6 (x86_64) 虚拟机mysql 做从库  版本为 5.5.38, fo ...

  4. IAP内购 返回的产品数量为0

    上个月搞IAP,提交到appstore审核被拒,根据附件截图 可以知道是请求产品信息的时候,产品数量返回0了. 返回产品数量为0 要么是Itunes Connect 里面的Contracts Tax ...

  5. ColorComboBox

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...

  6. 今天就注册上海ORACLE2用户组014在峰会酒吧!

    COLLABORATE 14 – SHOUG Forum 上海ORACLE用户组2014年高峰论坛报名本次活动由ORACLE ACS高级服务部门与 SHOUG 上海ORACLE用户组合办. 大会议程包 ...

  7. Android编程动态创建视图View的方法

    在Android开 发中,在Activity中关联视图View是一般使用setContentView方法,该方法一种参数是使用XML资源直接创 建:setContentView (int layout ...

  8. 为Android GridView 设置行背景

    经常有这样的需求,你的功能图标要像一个个物品,摆放在书架上,像这样: 我的思路比较简单,重载GridView,在他绘制子视图前,先把背景绘制完成 1 2 3 4 5 6 7 8 9 10 11 12 ...

  9. nginx 笔记

    nginx 这个轻量级.高性能的 web server 主要可以干两件事情: 〉直接作为http server(代替apache,对PHP需要FastCGI处理器支持): 〉另外一个功能就是作为反向代 ...

  10. centos安装g++

    安装: yum -y install gcc automake autoconf libtool make 安装g++: yum install gcc gcc-c++