Chapter 9 Advanced Socket Word Function Programming
· 9.1 Advanced usage of sending and receiving functions
Header file:
Int Send (int SockFD, Void * Buf, Int Len, Int Flags);
[flags = msg_oob, msg_dontwait, msg_dontroute]
Int Recv (int SockFD, Void * BUF, INT LEN, INT FLAGS);
[flags = msg_oob, msg_peek, msg_waitall, msg_dontroute]
Header file:
Int Readv (INT FD, STRUCT IOVEC * IOV, INT IOVLEN); / / Read the socket buffer data into multiple application buffers
INT Writev (INT FD, STRUCT IOVEC * IOV, INT IVLEN); // Write multiple application buffers into socket buffer data
Struct Iovec {
Void * Iov_base ;. // Point to the array of application buffer structures
Size_t ip_len; // Number of buffers
}
Header file:
INT Recvmsg (int SockFD, Struct Msghdr * msg, int flag); // is commonly used in Unix domain sets
INT sentmsg (int SockFD, Struct Msghdr * MSG, INT FLAG); // Inter-process Send / Receive File Descriptor
Struct msghdr {
Void * msg_name; // address information of the sender
INT msg_namelen; //
Struct IOVEC * MSG_IOV; // Buffer Structure Pointer
INT msg_iovlen; // buffer number
Void * msg_control; // Control information
INT MSG_Controllen; // Control information length
INT msg_flags;
}
When using these two functions, it is usually necessary to define the following structures:
Union {
Struct CMSGHDR CM;
Char Control [CMSG_SPACE (SIZEOF (Additional Segment Length)];
}
Operating macro, header file:
Struct cmsghdr * cmsg_firsthdr (struct msghdr * msghdrptr); // Point to the first CMSGHDR structure pointer
Struct CMSGHDR * CMSG_NEXTHDR (Struct Msghdr * Msghdrptr, Struct CMSGHDR * CMSGPTR);
Unsigned char * cmsg_data (struct cmsghdr * cmsghdr); // Returns the first byte of the CMSGHDR structure
Unsigned cmsg_len (unsigned int future); // Get the number of data bytes in CMSGHDR
Chapter 10 Guarding Process and Super Server inetd
· 10.1 Principle of daemon
As long as the system does not shut down or crash, the daemon will run uninterrupted in the system. The key is how to isolate the runtime environment of the daemon and other processes. step:
1 First Fork and Setsid function call to establish a new session group
The main purpose of this operation is to let a process and control terminals out of the terminal, so that the signal from the terminal will not affect the daemon. The function of the setsid () function is to create a new session process and let the process of calling the setsid () become the leading process of the session process. But the call condition of SetsId () is that this process is not a main process of a process group. So let's first form () a child process and terminate the operation of the process group main process, calling the setsid () in the child process into the leading process of the new session process without the control terminal. So this process is detached from the original control terminal and becomes a leadership process for the new session group. 2 Second Fork and SetPGRP function call to establish a new process group
After calling SetsID (), although the leadership process in the new session group does not have a control terminal. But if this process opens a terminal, the entire session group will re-control the terminal. So we need a new child process to continue to run and terminate the running process of the session group leader. At this point, this new process is not a session group leadership process, so even if you open a terminal, it will not be a control terminal for the entire session group.
However, because the parent process is the leading process of the session group, if the child process continues to run, SIGHUP (interrupt and suspend signal) will be sent to all processes in this session group. So we must first ignore the signal SIGHUP, then refork, then exit the parent process and continue to run.
However, this new process still and has exited the parent process in one process group, still subject to the signal impact in the same process group. So we have to use setpgrp () to make this process a leader in new process groups.
3 Turn off all file descriptors
The child process will inherit the file descriptor of the Parent process. We need to turn off the previously opened file descriptors in the daemon to avoid affecting other processes. Use the sysconf (_sc_open_max) function to get the maximum number of files in the system, and then use Close () to close them.
4 Eliminate the impact of umask
Each process has a umask with it. Umask specifies the protection mask of the process to create a file, which is a security mechanism provided by the system, and the restrictions on the process of creating files. For example, the process creates a file is 0777, the process umask is 0277, then the actual file authority is 0777-0277 = 0500. At this point, if other processes go to the written daemon, the files created by the daemon may be affected by the file mask. Use umask (0) system call to clear the old file mask.
5 Change the current directory of the daemon
Each process has a current directory that the error message can be recorded in the Core file of the current directory when the process generates an error. If you do not modify the daemon to a secure directory, the current directory of the daemon is uncertain and may affect the management of other systems. We can use chDIR ("/"); modify the daemon current directory to the root directory.
6 to the standard I / O descriptor
Since the daemon does not connect to any control terminal, all file descriptors are turned off. Then, if you accidentally call Printf, PERROR, etc. will result in an error. We reset the standard I / O to the Harmless Device descriptor, then the operation of the standard I / O will ignore the avoidance of human accidents.
7 Use syslog to record the error of the daemon
Syslogd itself is a daemon and uses UDP 514 ports. The application can send UDP packet logging error messages. Void Syslog (int priority, const char * message, ...); // # incluse
8 file lock and control daemon copy mutual exclusive operation
To avoid interference generated by multiple identical daemons, the operation of the daemon is recorded using the lock file. The LINUX system locks uses a consultation lock, just the system will inform the file to lock the situation without preventing the process to operate on the file. We can use int FLOCK (int FD, int Operation); // # include
Sample code:
INT init_daemon (const char * pathname, int facility);
{
Struct SigAction Act;
Int Max_fd, i, return;
INT LOCK_FD;
Char BUF [10];
// Open a file lock
Lock_fd = Open (LockFile, O_RDWR | O_CREAT, 0640);
IF (Lock_FD <0)
Error_Proc ();
/ / Parked
Ret = flock (lock_fd, lock_ex lock_nb);
IF (RET <0)
Error_Proc ();
// First Fork
Ret = fork ();
IF (RET <0)
Error_Proc ();
Else IF (RET! = 0)
EXIT (0); // Close the main process of the process group, the child process continues to run
Ret = setsid (); // This child process becomes a leadership process for new session groups
IF (RET <0)
Error_Proc ();
/ / Ignore SIG_IGN
Act.sa_handler = SIG_IGN;
SiGemptySet (& Act.sa_mask);
Act.sa_flag = 0;
SigAction (Sighup, & Act, Null);
// Second Fork
Ret = fork ();
IF (RET <0)
Error_Proc ();
Else
EXIT (0); // Close the main process of the process group, the child process continues to run
CHDIR ("/"); // Change the current directory of the daemon
umask (0); // Clear old file mask
setpgrp (); // Let this process become a leadership process for new process groups
Sprintf (buf, "% 6d / n", getpid ()); // Get the ID number of the daemon, save into the BUF array
Write (Lock_FD, BUF, Strlen (BUF)); // Save the daemon ID number in the lock file
Max_fd = sysconf (_sc_open_max); / / Get the most open descriptor for the process
For (i = 0; i Close (i); // close one by one Open ("dev / null", o_rdwr); // Open no harmful equipment DUP (1); // DUP (2); // Standard I / O descriptor OpenLog (Pathname, Log_PID, FACILITY); / / Open Syslogd Record File Return 0; // The daemon has ended } · 10.2 Hyper server inetd works Since the server socket initialization is very similar, you can design a dedicated server responsible for initialization, and it will work according to the corresponding service programs different from the access port, these service programs are in sleep before being accessed. status. The use of super servers can make the server program to manage in a unified manner.