http://blog.csdn.net/tianmohust/article/details/8691644
In the case of using a non-blocking socket in Linux.
(a) When sending
When a customer sends a large packet via the Send function provided by the socket, a eagain error may be returned. This error occurs because the size variable in the Send function exceeds the value of Tcp_sendspace. Tcp_sendspace defines the amount of data that an app can cache in kernel before calling send. When the application sets the O_ndelay or O_nonblock property in the socket, send returns a eagain error if the sending cache is full.
To eliminate this error, there are three ways to choose:
1. Increase the tcp_sendspace to be larger than the size parameter in send
---no-p-o tcp_sendspace=65536
2. Set a larger value for SNDBUF in the SetSockOpt function before calling send
3. Use write instead of send because write is not set O_ndelay or O_nonblock
(b) Upon receipt
Receive data often encounter resource temporarily unavailable prompt, errno code is one (Eagain). This indicates that you have a blocking operation in non-blocking mode, which returns the error if the operation is not completed, which does not break the synchronization of the socket, regardless of the next loop and then recv. For non-blocking sockets, Eagain is not an error. On VxWorks and Windows, Eagain is named Ewouldblock. In fact, this is not a mistake, just an anomaly.
Additionally, if EINTR is present as errno 4, the error description interrupted system call, the operation should also continue.
Finally, if the return value of recv is 0, it indicates that the connection has been disconnected and our receive operation should end.
(iii) The following is another explanation
If the sender traffic is larger than the traffic at the receiving end (meaning that the Epoll program reads faster than the forwarded socket), the Send () function returns, but the actual buffer data is not actually sent to the receiving end, as the non-blocking socket, A eagain error occurs when the buffer is full (refer to man send), while ignoring the data sent by this request. So,
A function that encapsulates socket_send () is used to handle this situation, and the function will try to write the data back and return 1 to indicate an error. Inside Socket_send (), when the write buffer is full (send () returns 1, and errno is Eagain), it waits and retries. This is not a perfect approach, and in theory it may be possible for a long time to clog up within the socket_send (), But there is no better way. This approach is similar to the READN and Writen packages (written by yourself, also described in advanced Programming for UNIX environments)
[CPP]View Plaincopy
- size_t socket_send (int sockfd, const char* buffer, size_t buflen)
- {
- size_t tmp;
- size_t total = Buflen;
- const Char *p = buffer;
- While (1)
- {
- TMP = Send (SOCKFD, p, total, 0);
- if (tmp < 0)
- {
- //When send receives a signal, it can continue writing, but here it returns-1.
- if (errno = = eintr)
- {
- return-1;
- }
- //When the socket is non-blocking, such as returning this error, indicates that the write buffer queue is full,
- //do a delay here and try again.
- if (errno = = Eagain)
- {
- Usleep (1000);
- continue;
- }
- return-1;
- }
- if ((size_t) tmp = = total)
- {
- return buflen;
- }
- Total-= tmp;
- p + = tmp;
- }
- return tmp;
- }