Daemon XINETD and SOCKET program

xiaoxiao2021-03-06  111

1.xinetd provides a passive super service, that is, the service program is started to be used, and there is no need to exist. For example, FTP, Telnetd, POP3, IMAP, AUTH, etc. are no need to start when they are used. In addition, Xinetd converts socket to stdin / stdout, thus makes the network service program design greatly simplified, you can complete the complex network protaguitable using only Printf and Fgets.

2. A simple service program Goodie #include #include #include

Char * cmds [] = {"Help", "Say", "Hello", "Bye", "EXIT", NULL};

INT getcmd (char * cmd) {INT N = 0; while (cmds [n]! = null) {IF (StrncaseCMP (cmd, cmds [n], strlen (cmds [n])) == 0) Return n; N ;} return -1;

Void main (void) {char Buf [1024]; int OK;

Printf ("Welcome to Goodie Service!"); FFLUSH (stdout);

OK = 0; do {while (FGETS (BUF, 1023, stdin) == null); Switch (BUF)) {CASE-1: Printf ("Unknown Command!"); Break; Case 0: Printf (" How May I Help You, SIR? "); INT J = 0; While (CMDS [J ]! = NULL) Printf ("% S / T / T ", CMDS [J-1]); Break; Case 1: Printf ("I Will Say% S", & Buf [3]); Break; Case 2: Printf ("How're you doing today?"); Break; Case 3: Printf ("Si Ya, Mate!"); OK = 1; Break; Case 4: Printf ("Go Ahead!"); OK = 1; Break;} fflush (stdout);} while (!!);

} 3. Configuration files Add to the following items in / etc / services, the item name is the goodie service port is the 12345 service type is TCP in the /etc/xinetd.d directory new inspection service file Goodie Enter content service goodie {socket_type = stream protocal = tcp wait = no server = / {goodie dir} / goodir disable = no # initialized to turn on service listening} 4. Start service Stop service KILLALL XINETD boot service / usr / sbin / xinetd -f / etc / xinetd .conf

5. Open the terminal connection telnet localhost 12345

-------------------------------------------------- -------------------------------------------------- -------------- 6.xineTD works by configuring Xinetd, then view the corresponding sockets and processes, you can see that xinetd is working (targeting TCP services) A. Read the /etc/xinetd.conf file at startup and create a corresponding socket (stream or datagram) for all services specified in the file, the number of services that the XINETD can detrimentally depend on the number of sockets created. Each newly created socket is added to the descriptor set used by the SELECT call. B. Call Bind for each socket, bind the service port (defined in / etc / services), and the port number is obtained by calling GetServByname. C. After all sockets are established, call SELECT Wait to be readable, change when there is a data report on the TCP socket to be readable. XINETD is increasing at the call of SELECT; D.xinetd daemon, the sub-process processing service request; the child process closes all the description words other than the socket to be processed, the child process three times call DUP2, set The text description word is copied to 0, 1, 2, and then turn off the original connector; after the program is operated on 0, 1, 2, and the child process exec executes the corresponding server program, and put the configuration file Parameter delivery. E. Because the TCP server typically sets the NOWAIT tag, it is indicated that the xinetd must wait before the socket is selected again, and must wait for the child process to serve on the socket. Therefore, when the Fork in the parent process returns, the process number of the child process is recorded, so that when the child process is terminated, the parent process can use WaitPid's return value to the one child process; the parent process uses fd_clr macro off Select SELECT The description of the description is set to the bit corresponding to this socket so that the socket is not written. When the child process is terminated, the parent process receives a SIGCHLD signal, the signal handler of the parent process gets the process number of the terminator process. The parent process restores the SELECT to the socket by opening the corresponding bit in the description word.

7. Re-implement XINETD super daemon

A. The program uses the above principle to re-realize the super daemon. B. The program is only a conceptual code in some places, and it is fully implemented. C. The program can demonstrate the function of xinetd, but in the comments, there is a bug and Note, you need to improve D. This is a summary information, referring to "UtrandD to implement UDP daemon" and "www.douzhe.com" Article.

#include #include #include

#include #include

#include #include #include

#include #include // Assign each service a message structure that contains socket, and path. Struct param {int suck; // Bind's socket char path [256]; // Server path PID_T PID; // Child process ID Struct param * next;

FD_set readfds; struct param * pHead, * ptail, * p; / * Respond to the signal function ended in the sub-process; if the service is wait = yes; bind socket must wait until the child process ends to listen to the next request * / void signal_handler (int Signum) {PID_T PID; PID = WaitPID (-1, null, wuntraced); for (p = phead; p! = null; p = p-> next) IF (P-> PID == PID) {// fd_set (P-> SOCK, & READFDS; Printf ("Child Exit PID =% D / N", PID); Break;} Signal (Sigchld, Signal_Handler);

INT MAIN (int Argc, char * argv []) {Int Sock, ss; int nret; int suck_len; struct sockaddr_in addr; struct sockaddr_in addr_clt; file * file; fd_set testfds;

Sock_len = sizeof (addr); p = (struct param *) Malloc (Struct param); ptail = p; phead = null;

P-> SOCK = Socket (AF_INET, SOCK_STREAM, 0); // file = fopen ("/ etc / xinetd.conf", "r"); // while (1) / / omitted from "/ etc / xinetd. Read each service and start {addr.sin_family = Af_inet; addr.sin_addr.s_addr = htonl (inaddr_any); addr.sin_port = htons (9734); // Read service from "/ etc / service" file Port number GetServbyName; bind (p-> sock, (struct socaddr *) & addr, sock_len; listen (p-> sock, 5);

FD_ZERO (& READFDS); FD_SET (P-> Sock, & ReadFDs); STRCPY (P-> Path, "~ / Socket /"); / / omitted from the path to each service from the "/etc/xinetd.conf" file IF (PHEAD == NULL) {P-> Next = Null; PHEAD = PTAIL = P; Printf ("PHEAD == NULL / N");} else {ptail-> next = p; ptail = p; ptail-> Next = NULL;

} Printf ("Path =% S, SOCK =% D / N", PHEAD-> Path, PHEAD-> SOCK);

While (1) {Int fd; int clientfd; int N; pid_t pid; int flag = 0;

Testfds = readfds; NRET = SELECT (fd_setsize, & testfds, null, null, null); // if (NRET <0) {PERROR (STRERROR (Errno)); EXIT (5);} // Bug 1: If the child process End will display "Interrupt System Call" error. For (fd = 0; fd next) ing (p-> sock == fd) {Printf ("Child Runing / N "); // execve (); // Note 1: Unmarkled Server path (file)} Sleep (1); exit (5); default: //> 0 Close (ClientFD); if (flag) / / Note 2: Decide FD_CLR (FD, & ReadFDs) by Service Name; for (P = PHEAD; P! = NULL; P = P-> Next) IF (P-> SOCK == FD) {P-> PID = PID; P RINTF ("SOCK:% D, Child PID =% D / N", P-> Sock, P-> PID);} Signal (SIGCHLD, SIGNAL_HANDAL); // Note 3: Start, or here? Break;}}}}}

For details, please refer to http://www.xinetd.org/

转载请注明原文地址:https://www.9cbs.com/read-98901.html

New Post(0)