Exceptions caused by setting SO_LINGER for NIO

Source: Internet
Author: User

Welcome to Github: https://github.com/teaey/


### Background

I want to migrate from Netty3 to netty4.

The reason is that Netty3 reports an error in the container, error Stack:

Java. io. IOException: an unblocking socket operation cannot be completed immediately.

At sun. nio. ch. SocketDispatcher. close0 (Native Method)

At sun. nio. ch. SocketDispatcher. preClose (SocketDispatcher. java: 44)

At sun. nio. ch. SocketChannelImpl. implCloseSelectableChannel (SocketChannelImpl. java: 677)

At java. nio. channels. spi. AbstractSelectableChannel. implCloseChannel (AbstractSelectableChannel. java: 201)

At java. nio. channels. spi. AbstractInterruptibleChannel. close (AbstractInterruptibleChannel. java: 97)

### Analysis

I have never encountered this problem before, but if netty3 has this problem, netty4 should also exist. Let's see what causes this problem.
Find the close0 method of SocketDispatcher. This is a local method:
Find the Windows implementation:
On Windows, the socket is closed by calling closesocket (winsock2.h. Next, you can view the official document of the huge hardware. The content is summarized as follows:
If no error occurs, closesocket returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
This means that if 0 is returned correctly and SOCKET_ERROR is returned if the error is returned. You can use the WSAGetLastError function to obtain the error status.
It is obvious that an error occurs and an exception is thrown up. By analyzing the error status information of closesocket and Google's "unable to complete a non-blocking socket operation immediately", the system is diagnosed with the error status WSAEWOULDBLOCK.
Read the official documentation and learn that the error status is caused by SO_LINGER.
So I went back and looked at the code. The figure shows the captured Netty code snippet:

This is the case in the document:
Setting the l_onoff member of the linger structure to nonzero and the l_linger member with a nonzero timeout interval on a nonblocking socket is not recommended.
It means that the SO_LINGER parameter is not recommended in the case of non-blocking Socket.
In this case, the call to closesocket will fail with an error of WSAEWOULDBLOCK if the close operation cannot be completed immediately. if closesocket fails with WSAEWOULDBLOCK the socket handle is still valid, and a disconnect is not initiated. the application must call closesocket again to close the socket.
If SO_LINGER is set and the timeout time is set, we call the closesocket method. If the method cannot be completed immediately, the WSAEWOULDBLOCK error will be thrown. However, this socket is valid at this time. You can call the close method again after a while to close the socket.

### Solution

However, java throws a simple IOException, and we cannot determine whether it is a WSAEWOULDBLOCK error. It is difficult to determine whether IOException is caused by other reasons, so it is impossible to retry.
Finally, the solution is removed.
This line of code.
After improvement, when the close method is called, no exception will be thrown. Before the underlying socket is closed, the system will try to send the data in the Buffer Queue to the peer end. The original article is as follows:
If the l_onoff member of the LINGER structure is zero on a stream socket, the closesocket call will return immediately and does not receive whether the socket is blocking or nonblocking. however, any data queued for transmission will be sent, if possible, before the underlying socket is closed.

### Conclusion

When using NIO, it is best not to configure SO_LINGER. If this parameter is set, if there is data to be written in the buffer during close, an IOException will be thrown.
Note: Recently, we found that Zookeeper versions earlier than Zookeeper have also set this parameter and removed this parameter in the latest version. Is it true that the code of these experts is Ctrl + C, ctrl + V. Haha.

### References

  1. Http://msdn.microsoft.com/en-us/library/windows/desktop/ms737582 (v = vs.85). aspx
  2. Http://msdn.microsoft.com/en-us/library/windows/desktop/ms741580 (v = vs.85). aspx
  3. Http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668 (v = vs.85). aspx # WSAEWOULDBLOCK

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.