【MediaSoup---初级篇】(一)服务器基础编程

一个最简单的服务器程序

server.h

/**
 * Server Class 
 *
 * @author lichao
 * @date 2019-08-07
 * @copyleft GPL 2.0
 */

#ifndef __SERVER_H__
#define __SERVER_H__

namespace avdance {

class Server {

  public:
    Server();  //consrtuct
    ~Server(); //destruct

  public:
    void run();

};

} //namespace avdance

#endif //__SERVER_H__

server.cpp

/**
 * the implement of Server Class 
 *
 * @author lichao
 * @date 2019-08-07
 * @copyleft GPL 2.0
 */

#include <iostream>
#include <unistd.h>

#include "server.h"


namespace avdance {

Server::Server(){
  std::cout << "Server construct..." << std::endl;
}

Server::~Server(){
  std::cout << "Server destruct..." << std::endl;
}

void Server::run(){
  while(1){
  
    std::cout << "the server is runing..." << std::endl;
    ::usleep(1000000); //us sleep 1 second 

  }
}

} // namesapce avdance

main.cpp

/**
 * a server
 *
 * @author lichao
 * @date 2019-08-07
 * @copyleft GPL 2.0
 * g++ -std=c++11 -g -o server main.cpp server.cpp
 */

#include <iostream>
#include "server.h"

int main(int argc, char* argv[])
{
  
  avdance::Server* server = new avdance::Server();

  if(server){
    server->run();
  }

  return 0;
}

关于信号

信号处理的三种方式

忽略;捕获;默认处理。

Linux下有哪些信号

man 7 signal 可以用来查看信号情况

安装man中文手册

几个重要的信号

SIGPIPE 管道中止,当写入无人读取的管道时产生该信号默认终止进程

SIGCHLD 子进程结束或者停止时发送。

SIGALRM 定时器信号,以秒为单位,默认终止进程

SIGUSR1/SIGUSR2 自定义,默认终止进程

SIGINT 键盘输入的退出信号

SIGQUIT 键盘输入的退出信号

SIGHUP 控制终端的挂起信号

信号发送方式

安装信号

信号处理的简单方式

#include<iostream>

#include<signal.h>
#include<unistd.h>

//信号处理回调函数
void sighandle(int sig){
   std::cout<< "receved signal:"<<sig<<std::endl;
		
}    

int mian()
{
    signal(SIGINT,sighandle);
	
	pause();
	return 0;
}

信号处理的高级方式

后台服务

fork方式

//#include "apue.h"
#include <stdio.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/resource.h>

/**
 * 注释1:因为我们从shell创建的daemon子进程,所以daemon子进程会继承shell的umask,如果不清除的话,会导致daemon进程创建文件时屏蔽某些权限。
 * 注释2:fork后让父进程退出,子进程获得新的pid,肯定不为进程组组长,这是setsid前提。
 * 注释3:调用setsid来创建新的进程会话。这使得daemon进程成为会话首进程,脱离和terminal的关联。
 * 注释4:最好在这里再次fork。这样使得daemon进程不再是会话首进程,那么永远没有机会获得控制终端。如果这里不fork的话,会话首进程依然可能打开控制终端。
 * 注释5:将当前工作目录切换到根目录。父进程继承过来的当前目录可能mount在一个文件系统上,如果不切换到根目录,那么这个文件系统不允许unmount。
 * 注释6:在子进程中关闭从父进程中继承过来的那些不需要的文件描述符。可以通过_SC_OPEN_MAX来判断最高文件描述符(不是很必须).
 * 注释7:打开/dev/null复制到0,1,2,因为dameon进程已经和terminal脱离了,所以需要重新定向标准输入,标准输出和标准错误(不是很必须).
 */
void daemonize(const char *cmd){
  int i, fd0, fd1, fd2;
  pid_t pid;
  //struct rlimit rl;
  //struct sigaction sa;

  /* * Clear file creation mask. */
  //umask(0);//注释1

  /* * Get maximum number of file descriptors. */
  //if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
  //  err_quit("%s: can't get file limit", cmd);

  /* * Become a session leader to lose controlling TTY. */
  if ((pid = fork()) < 0) {//注释2
    printf("%s: can't fork", cmd);
    exit(-1);
  }
  else if (pid != 0) /* parent */
    exit(0);

  setsid();//注释3

  /* * Ensure future opens won't allocate controlling TTYs. */
  /*
  sa.sa_handler = SIG_IGN;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;

  if (sigaction(SIGHUP, &sa, NULL) < 0)
    err_quit("%s: can't ignore SIGHUP", cmd);
  if ((pid = fork()) < 0)//注释4
    err_quit("%s: can't fork", cmd);
  */
  /*else if (pid != 0) *//* parent */
  /*
    exit(0);
  */

  /* * Change the current working directory to the root so * we won't prevent file systems from being unmounted. */
  if (chdir("/") < 0) {//注释5
    printf("%s: can't change directory to /", cmd);
    exit(-1);
  }


  /* * Close all open file descriptors. */
  /*
  if (rl.rlim_max == RLIM_INFINITY)
    rl.rlim_max = 1024;

  for (i = 0; i < rl.rlim_max; i++)
    close(i);//注释6
  */

  /* * Attach file descriptors 0, 1, and 2 to /dev/null. */
  fd0 = open("/dev/null", O_RDWR);//注释7
  //fd1 = dup(0);//注释7
  //fd2 = dup(0);//注释7
  dup2(fd0, STDIN_FILENO);
  dup2(fd0, STDOUT_FILENO);
  dup2(fd0, STDERR_FILENO);

  /* * Initialize the log file. */
  /*
  openlog(cmd, LOG_CONS, LOG_DAEMON);
  if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
    syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);
    exit(1);
  }
  */

}

int main(int argc, char* argv[])
{
  daemonize("test");

  while(1)
  {
    sleep(60);
  }

}

daemon API

#include <unistd.h>
#include <stdlib.h>

int main(void)
{
  if(daemon(0,0) == -1)
    exit(EXIT_FAILURE);
  while(1)
  {
    sleep(60);
  }
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

༄yi笑奈何

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值