Errno
In UNIX systems where most system calls are returned abnormally, the return value is typically-1, and the global variable errno (errno.h), such as socket (), bind (), accept (), listen () is set. Erron holds a positive integer to hold the error value of the last error.
For threads, each thread has a dedicated errno variable, regardless of the synchronization problem.
Strerror converts to 中文版 (Note:use strerror_r for thread safety)
Perror is simplified strerror/fprintf
Slow system calls
Refers to system calls that can be blocked forever and cannot be returned, usually some examples of read and write, such as pipe, terminal equipment, network connection, typical accept (), read (), write (), open (), select (), Epoll (), etc. The basic rule for slow system calls is that when a process blocking a slow system call captures a signal and the corresponding signal processing function returns, the system call may return a EINTR error that will set the value of errno to that value. Although some cores will be restarted for this system call, from a portability standpoint, it is necessary to eintr processing. Note that the connect () cannot be handled this way. (UNP 5.9)
A signal is responded to by a signal processing function, which is masked during processing. The standard signal implementation does not have a queued function, so the signal may be lost, and multiple successive signals are too late to process. Checking with Waidpid () enumeration is a good solution, see UNP 5.10
About Toe (TCP offload engine)
A small detail for a local clutch:
Checksum incorrect appears. is caused by the toe engine on the NIC. TOE Wiki
The TCP/IP protocol is used to handle network traffic, which consumes a lot of server resources. In order to relieve the pressure of the server, a kind of technology called TCP Offload Engine:toe is born. TCP Offload engine is generally composed of two parts of soft and hard components, extending the function of the traditional TIP/IP protocol stack, and transferring the processing of network data traffic to the integrated hardware on the NIC, the server only undertakes the processing task of TCP/IP control information.
Generally by the operating system's TCP/IP stack to complete the calculation of TCP/UDP/IP checksum, the function of integrated toe in the NIC will include computational checksum. After setting the RX Checksum offload/tx Checksum Offload to enable, the protocol stack is not computed for checksums, but is done by the NIC itself.
Modify the properties of the NIC to avoid Checksum incorrect, disable Checksum offload. Checksum incorrect can be corrected at the cost of network performance degradation.
The problem with this checksum seems to have little effect on the application layer's program ... (Personal feeling)
I/O processing on the socket
The standard I/O library mentioned in the preceding (standard I/O summary) is a set of advanced input and output functions defined by ANSI C, which is more convenient than the system I/O directly using UNIX.
However, the standard I/O library does not provide a way to read file metadata, nor is it appropriate to handle special files of the socket class.
Insufficient value (short count)
Definition, in short, I want to handle 10 bytes, only 6 processed, then the low value is 6. Note Not 4.
Read and write actually processed fewer bytes than expected due to the limited buffer size of the socket in the kernel and the reason for network latency. Others may also experience low values if they encounter EOF or read from a terminal
No insufficient value when reading and writing disk files
Processing method:
UNP 3.9 and Csapp 10.9 (RIO) All give a solution, for reference, the following code:
int simon_send (int fd, char* buf, unsigned int n) {int left = N;char *bufptr = Buf;int send_bytes;while (left >= 0) {if ( (send_bytes = Send (FD, bufptr, max_buf_size, 0)) < 0) {if (errno = = eintr) //iterrupted by signal, send agains End_bytes = 0;elsebreak;} else if (!send_bytes) //EOF or socket shutdown by peerbreak;left-= send_bytes;bufptr + = send_bytes;} return n-left;} int simon_recv (int fd, char* buf, unsigned int n) {int left = N;char *bufptr = Buf;int recv_bytes;while (left >= 0) {if ( (recv_bytes = recv (FD, BufPtr, max_buf_size, 0)) < 0) {if (errno = = eintr) recv_bytes = 0;elsereturn-1;} else if (!recv_bytes) break;left-= recv_bytes;bufptr + = recv_bytes;} return n-left;}
In addition, the use of recv with marked Msg_waitall can also be processed to some extent.
About I/O selection and comparison, visible (excerpt from a ppt):