linux network IO

Use reactor mode to simulate asynchronous IO
http://www.artima.com/articles/io_design_patterns.html
system function:
http://linux.die.net/man/4/epoll


call read/write on a non-blocking socket Function, return EAGAIN or EWOULDBLOCK (Note: EAGAIN is EWOULDBLOCK)
Literally, it means: EAGAIN: try again, EWOULDBLOCK: if this is a blocking socket, the operation will be blocked, perror output: Resource temporarily unavailableSummary
:
this The error indicates that the resources are temporarily insufficient. When reading is possible, the read buffer has no data, or when writing, the write buffer is full. In this case, if the socket is blocked, read/write will be blocked. And if it is a non-blocking socket, read/write returns -1 immediately, and errno is set to EAGAIN.
So, for blocking sockets, read/write returns -1 to indicate a network error. But for non-blocking sockets, read/write returns -1 not necessarily the network is really wrong. May be Resource temporarily unavailable. At this point you should try again until Resource is available.
In summary, for non-blocking sockets, the correct read and write operations are:
read: ignore the error of errno = EAGAIN, continue reading
and write : ignore the error of errno = EAGAIN, continue to write next time
For the LT mode of select and epoll, this way of reading and writing is no problem. But for epoll's ET mode, this method still has loopholes.
The difference between the two modes of epoll, LT and ET
, is that in the level-trigger mode, as long as a socket is in the readable/writable state, the socket will be returned whenever epoll_wait is performed; while in the edge-trigger mode, only a socket is unreadable from the unreadable state. epoll_wait will only return the socket when it becomes readable or changes from unwritable to writable.
Therefore, in the ET mode of epoll, the correct way of reading and writing is:
read: as long as it is readable, keep reading until it returns 0, or errno = EAGAIN
write: as long as it is writable, keep writing until the data is sent, or errno = EAGAIN



Author: Guo Wuxin
Link : http://www.zhihu.com/question/22524908/answer/69054646
Source

: Zhihu Level-triggered (level-triggered, also known as conditional trigger) LT: As long as the conditions are met, Trigger an event (as long as there is data that is not fetched, the kernel keeps notifying you)
edge-triggered (edge-triggered) ET: Whenever the state changes, trigger an event.

Java's NIO is a horizontal trigger, that is, a conditional trigger.

Therefore when using Java's NIO programming, you need to cancel the write event when there is no data to write, and then register the write event when there is data to write.


The most unbearable thing about select is that the FD opened by a process has a certain limit, which is set by FD_SETSIZE, and the default value is 2048. Obviously too few for IM servers that need to support tens of thousands of connections. At this time, you can choose to modify this macro and then recompile the kernel, but the data also pointed out that this will bring about a decrease in network efficiency.

However , epoll does not have this limitation. The upper limit of the FD it supports is the maximum number of open files. This The number is generally much larger than 2048. For example, it is about 100,000 on a machine with 1GB of memory. The specific number can be viewed by cat /proc/sys/fs/file-max. Generally speaking, this number has a great relationship with the system memory.

Another Achilles heel of traditional select/poll is when you have a large set of sockets, but due to network latency, only some of the sockets are "active" at any one time, but select/poll scans all of them linearly for each call. , resulting in a linear decrease in efficiency. But epoll does not have this problem, it only operates on "active" sockets---this is because epoll is implemented according to the callback function above each fd in the kernel implementation. Then, only the "active" socket will actively call the callback function, and other idle state sockets will not

use mmap to speed up the message passing between the kernel and user space.
This actually involves the specific implementation of epoll. Whether it is select, poll or epoll, the kernel needs to notify the user space of the FD message. It is very important to avoid unnecessary memory copying. At this point, epoll is implemented by the kernel and the user space mmap the same piece of memory.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326943404&siteId=291194637