聊天服务器——服务器的开始

一个服务器的开始

后台运行

如何开启一个后台运行程序

参数处理

头文件 #include<unistd.h>

函数说明getopt( )用来分析[命令行参数]

getopt就是linux中常用的后面带个-a -b -c这种

char *optstring = “ab:c::”;

单个字符a 表示选项a没有参数 格式:-a即可,不加参数

单字符加冒号b: 表示选项b有且必须加参数 格式:-b 100或-b100,但-b=100错

单字符加2冒号c:: 表示选项c可以有,也可以无 格式:-c200,其它格式错误  

optarg —— 指向当前选项参数(如果有)的指针。

optind —— 再次调用 getopt() 时的下一个 argv指针的索引。 

optopt —— 最后一个未知选项。 

opterr ­—— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。

信号处理

signal函数

signal(SIGCHLD, SIG_DFL);   //SIG_DFL默认
signal(SIGPIPE, SIG_IGN);   //SIG_IGN忽略信号
​

后台运行子进程

当后台运行子进程时

signal(SIGCHILD, SIG_IGN);           //子进程结束时会给父进程发一个信号。我们把这个信号忽略掉,让内核去回收子进程

我们把子进程忽略掉,让系统来回收子进程。

#include<sys/types.h>

#include<fcntl.h>

fork() 产生进程

int pid = fork();
//fork()=0 表示子进程
//fork() > 0 返回的是子进程的id
//fork() < 0 表示错误,比如内存不足

exit()表示结束进程

setsid()表示使进程成为会话组长

int dup(int oldfd) 复制文件描述符

int dup2(int oldfd, int newfd) 重定向文件描述符

int daemon()
{
   signal(SIGCHLD, SIG_IGN);
   int pid = fork();
   if(pid < 0)
   {
       cout << "fork call error, code is" << pid << "error code is" << errno << std::endl;
       exit(-1);
   }
   if(pid > 0) //主进程在此结束
   {
       exit(0);
   }
   
   //下面是子进程的代码
   //这里可以避免父进程所在的会话结束时,把子进程带走
   //不让前台影响后台,setsid是设置进程为会话组组长
   setsid();
​
   //不让后台影响前台
   int fd = open("/dev/null", O_RDWR, 0);
   cout << "fd is" << fd << std::endl
   int (fd != -1)
   {
       dup2(fd, STDIN_FILENO);
       dup2(fd, STDOUT_FILENO);
       dup2(fd, STDERR_FILENO);
       //就是把输入输出全部都定向到dev下的null,就是直接吃掉,避免终端上输入输出影响前台程序
   }
   if(fd > STDERR_FILENO)
       close(fd);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值