前面提到过的服务器都占有控制终端。而有些进程并不需要控制终端。比如我们想写一个回射服务器(既从终端得到信息,然后将数据再返回给终端,基于UDP因为比较简单)。
其实这并算不上一个难题,在shell中只要在指令后加上&就可以使服务器成为一个守护进程(后台进程)。但这里还是通过代码自己来实现。
#include "stdio.h"
#include "stdlib.h"
#include "/programe/net/head.h"
#include "syslog.h"
#include "sys/types.h"
#include "signal.h"
#include "string.h"
#define MAXSIZE 100
int main(int argc, char ** argv) {
openlog("echo_server2", LOG_CONS | LOG_PID, 0);
syslog(LOG_INFO | LOG_LOCAL0, "server start....");//利用syslog来写日志
if(fork() != 0)
exit(0);//父进程退出
//父进程退出后,shell就认为命令结束使得子进程在后台开始运行
setsid();
//子进程建立新的对话期,子进程继承了父进程的组进程号,该进程组的组长为父进程,所以子进程可以自己建立一个对话期,建立对话期的子进程不再有控制终端(详细可以看linux进程组,对话期)
signal(SIGHUP, SIG_IGN);
//忽略SIGHUP信号,这个作用下个解释会提到
if(fork() != 0)
exit(0);
//子进程再建立一个子进程,我们称第一个子进程为P1,有P1创建的子进程为P2。P1新建了一个对话期,P1就会作为这个对话期首进程,在SVR4中,作为对话期首进程的P1如果打开一个终端设备(如果这个设备不是其它对话期的终端),则该终端设备就会自动成为这个会话期的终端。创建P2,P2不是对话期的首进程即使打开终端设备也不会把该设备变成这个对话期的终端。(打开终端设备可以通过open(/dev/....))。前面之所以要忽略掉SIGHUP信号,是因为所谓对话期的首进程P1退出时候,会向对话期前台进程组的每一个进程发送SIGHUP信号,该信号默认操作是终止进程。
int i;
for(i = 0; i < 64; i++) {
close(i);
}
//关闭从父进程继承而来的描述字,这里我们并不知道一共有多少个描述字被打开(其实因该猜到只有3个),所以以64为标准,如果不想一个的标准输入输出函数出错(例如printf之类),可以将0,1,2描述字指向/dev/null。当然既然是后台守护进程,其实这也没多大必要
//后面的代码就见过很多次了
int sockfd;
struct sockaddr_in serv_socket;
char buf[MAXSIZE + 1];
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&serv_socket, sizeof(serv_socket));
serv_socket.sin_family = AF_INET;
serv_socket.sin_addr.s_addr = htonl(INADDR_ANY);
serv_socket.sin_port = htons(9843);
int flag = bind(sockfd, (struct sockaddr *)&serv_socket, sizeof(serv_socket));
if(flag == -1) {
syslog(LOG_DEBUG | LOG_LOCAL0, "bind error\n");
exit(1);
}
for(;;) {
struct sockaddr_in client_socket;
socklen_t len = sizeof(client_socket);
int n = recvfrom(sockfd, buf, MAXSIZE, 0, (struct sockaddr *)&client_socket, &len);
char client_ip[16];
inet_ntop(AF_INET, &client_socket.sin_addr, client_ip, sizeof(client_ip));
syslog(LOG_DEBUG | LOG_LOCAL0, "get message from %s\n", client_ip);
int flag = sendto(sockfd, buf, n, 0, (struct sockaddr *)&client_socket, sizeof(client_socket));
if(flag == -1)
syslog(LOG_DEBUG | LOG_LOCAL0, "send message to %s false\n", client_ip);
}
}
分享到:
相关推荐
通过redis,获取列表 操作html页面移动
因工作需要,用VB编写的一个进程守护程序,自动检测守护进程的运行状态(运行,未激活,无响应),再根据你的设置来重启未激活及无响应的进程。可根据需要来设置定时启动进程和系统的时间。定时启动进程时,自动结束...
使用VS2015开发的MFC服务器守护进程工具,网络传输部分使用CSocket+ProtoBuf的组合。该程序可以单独使用,也可以作为服务器端使用,配合下一个上传的 运维工具(守护进程客户端)。
vc++守护进程,守护一个程序的开启,关闭自动打开.
守护进程与其他网络服务器编程技术 守护进程是在后台运行不受终端控制的进程(如输入、输出等),一般的网络服务都是以守护进程的方式运行。 守护进程脱离终端的主要原因有两点: 用来启动守护进程的终端在启动守护...
以守护进程方式运行的信息服务器,含服务端与客户端 以守护进程方式运行的信息服务器,含服务端与客户端
0x03.第三课 MetaSploit实战对Apache HTTP服务器守护进程中断复现.pdf
LINUX守护进程介绍 amd:自动安装NFS(网络文件系统)守侯进程 apmd:高级电源管理 Arpwatch:记录日志并构建一个在LAN接口上看到的以太网地址和IP地址对数据库 Autofs:自动安装管理进程automount,与NFS相关,...
dynsdjs 采用NodeJS编写的简单DNS服务器守护进程
项目中使用python写一个监控程序,每隔5秒监控目录,发现文件就...为了谨防程序崩溃,特别编写一个守护进程程序,时刻监控程序是否崩溃并重新启动。 博文: http://blog.csdn.net/alex_bean/article/details/77923178
因为控制台程序出现过因为连接第三方服务超时直接挂掉(此时负载少了一个节点)以及服务器出现意外重启问题(该服务器所有节点宕机),所以需要一个进程守护程序。 也找过 现场的脚本、python的程序、pm2守护方式,...
守护进程时间服务器C语言实现,适合编程小白
提供这些服务的程序是由运行在后台的守护进程(daemons)来执行的。守护进程是生存期长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。他们常常在系统引导装入时启动
守护进程和inetd超级服务器PPT学习教案.pptx
使用VS2015开发的MFC运维工具,网络部分使用了CSocket+Protobuf的组合,主要与前一个上传的守护进程服务器端连接使用,可以远程监视和控制服务器上的守护进程。
第七讲 守护进程与其他网络服务器编程技术.ppt
postsrsd, 后缀发件人重写方案守护进程 PostSRSdPostSRSd通过基于tcp的查找表提供了发送方重写方案( SRS ) 。 如果邮件服务器作为转发器,则需要 SRS 。发件人重写方案崩溃课程假设服务器收到来自 alice@example.com...
一个php守护进程类。 用 PHP 实现的 Daemon 类。可以在服务器上实现队列或者脱离 crontab 的计划任务。 使用的时候,继承于这个类,并重写 _doTask 方法,通过 main 初始化执行。
大多数的解决方法是使用其他进程来守护服务器程序,如果服务器程序挂了,通过守护进程来启动服务器程序。 万一守护进程挂了呢?使用双守护来提高稳定性,守护A负责监控服务器程序与守护B,守护B负责监控守护A...
3.4 守护进程.....46 3.4.1 简介...46 3.4.2 守护进程的启动...........46 3.4.3 守护进程的错误输出............46 3.4.4 守护进程的建立....48 3.5 本章小结.....49 第四章进程间通信...50 4.1 进程间通信的一些...