public int getSoLinger() throws SocketException {if (isClosed())throw new SocketException("Socket is closed");Object o = getImpl().getOption(SocketOptions.SO_LINGER);if (o instanceof Integer) {return ((Integer) o).intValue();} else {return -1;}}
public void setSoLinger(boolean on, int linger) throws SocketException {if (isClosed())throw new SocketException("Socket is closed");if (!on) {getImpl().setOption(SocketOptions.SO_LINGER, new Boolean(on));} else {if (linger < 0) {throw new IllegalArgumentException("invalid value for SO_LINGER");}if (linger > 65535)linger = 65535;getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));}}
/*** Specify a linger-on-close timeout. This option disables/enables* immediate return from a <B>close()</B> of a TCP Socket. Enabling* this option with a non-zero Integer <I>timeout</I> means that a* <B>close()</B> will block pending the transmission and acknowledgement* of all data written to the peer, at which point the socket is closed* <I>gracefully</I>. Upon reaching the linger timeout, the socket is* closed <I>forcefully</I>, with a TCP RST. Enabling the option with a* timeout of zero does a forceful close immediately. If the specified* timeout value exceeds 65,535 it will be reduced to 65,535.* <P>* Valid only for TCP: SocketImpl** @see Socket#setSoLinger* @see Socket#getSoLinger*/@Native public final static int SO_LINGER = 0x0080;
在Java Socket中,当我们调用Socket的close方法时,默认的行为是当底层网卡所有数据都发送完毕后,关闭连接
通过setSoLinger方法,我们可以修改close方法的行为
- setSoLinger(true, 0)
- 当网卡收到关闭连接请求后,无论数据是否发送完毕,立即发送RST包关闭连接
- setSoLinger(true, delay_time)
当网卡收到关闭连接请求后,等待delay_time
如果在delay_time过程中数据发送完毕,正常四次挥手关闭连接
如果在delay_time过程中数据没有发送完毕,发送RST包关闭连接
