细说SocketOption,就是要让你懂TCP

Java的Socket的API中所有控制TCP的SocketOptions

                SO_KEEPALIVE     setKeepAlive
                SO_OOBINLINE     setOOBInline
                SO_RCVBUF          setReciveBufferSize
                SO_SNDBUF          setSendBufferSize 
                SO_TIMEOUT         setSoTimeOut     
                TCP_NODELAY      setTcpNoDelay
                SO_REUSEADDR  setReuseAddress
     /**
              * Connects this socket to the server with a specified timeout value.
              * A timeout of zero is interpreted as an infinite timeout. The connection
              * will then block until established or an error occurs.
              *
              * @param   endpoint the <code>SocketAddress</code>
              * @param   timeout  the timeout value to be used in milliseconds.
              * @throws  IOException if an error occurs during the connection
              * @throws  SocketTimeoutException if timeout expires before connecting
              * @throws  java.nio.channels.IllegalBlockingModeException
              *          if this socket has an associated channel,
              *          and the channel is in non-blocking mode
              * @throws  IllegalArgumentException if endpoint is null or is a
              *          SocketAddress subclass not supported by this socket
              * @since 1.4
              * @spec JSR-51
              */
    public void connect(SocketAddress endpoint, int timeout) throws IOException 三次握手,第二次syn+ack的超时时间
    
    /**
              * Create a server with the specified port, listen backlog, and
              * local IP address to bind to.  The <i>bindAddr</i> argument
              * can be used on a multi-homed host for a ServerSocket that
              * will only accept connect requests to one of its addresses.
              * If <i>bindAddr</i> is null, it will default accepting
              * connections on any/all local addresses.
              * The port must be between 0 and 65535, inclusive.
              * A port number of <code>0</code> means that the port number is
              * automatically allocated, typically from an ephemeral port range.
              * This port number can then be retrieved by calling
              * {@link #getLocalPort getLocalPort}.
              *
              * <P>If there is a security manager, this method
              * calls its <code>checkListen</code> method
              * with the <code>port</code> argument
              * as its argument to ensure the operation is allowed.
              * This could result in a SecurityException.
              *
              * The <code>backlog</code> argument is the requested maximum number of
              * pending connections on the socket. Its exact semantics are implementation
              * specific. In particular, an implementation may impose a maximum length
              * or may choose to ignore the parameter altogther. The value provided
              * should be greater than <code>0</code>. If it is less than or equal to
              * <code>0</code>, then an implementation specific default will be used.
              * <P>
              * @param port  the port number, or <code>0</code> to use a port
              *              number that is automatically allocated.
              * @param backlog requested maximum length of the queue of incoming
              *                connections.
              * @param bindAddr the local InetAddress the server will bind to
              *
              * @throws  SecurityException if a security manager exists and
              * its <code>checkListen</code> method doesn't allow the operation.
              *
              * @throws  IOException if an I/O error occurs when opening the socket.
              * @exception  IllegalArgumentException if the port parameter is outside
              *             the specified range of valid port values, which is between
              *             0 and 65535, inclusive.
              *
              * @see SocketOptions
              * @see SocketImpl
              * @see SecurityManager#checkListen
              * @since   JDK1.1
              */
    public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException { 
     //backlog:半连接队列的长度,默认50
        setImpl();
        if (port < 0 || port > 0xFFFF)
            throw new IllegalArgumentException(
                                           "Port value out of range: " + port);
        if (backlog < 1)
          backlog = 50;
        try {
            bind(new InetSocketAddress(bindAddr, port), backlog);
        } catch(SecurityException e) {
            close();
            throw e;
        } catch(IOException e) {
            close();
            throw e;
        }
    }

 

 

方法和参数详解

一、setSoLinger

在Java Socket中,当我们调用Socket的close方法时,默认的行为是当底层网卡所有数据都发送完毕后,关闭连接

通过setSoLinger方法,我们可以修改close方法的行为

1,setSoLinger(true, 0)

当网卡收到关闭连接请求后,无论数据是否发送完毕,立即发送RST包关闭连接

2,setSoLinger(true, delay_time)

当网卡收到关闭连接请求后,等待delay_time

如果在delay_time过程中数据发送完毕,正常四次挥手关闭连接

如果在delay_time过程中数据没有发送完毕,发送RST包关闭连接

/**
 * 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
 */

二、setKeepAlive

/**
 * When the keepalive option is set for a TCP socket and no data
 * has been exchanged across the socket in either direction for
 * 2 hours (NOTE: the actual value is implementation dependent),
 * TCP automatically sends a keepalive probe to the peer. This probe is a
 * TCP segment to which the peer must respond.
 * One of three responses is expected:
 * 1. The peer responds with the expected ACK. The application is not
 *    notified (since everything is OK). TCP will send another probe
 *    following another 2 hours of inactivity.
 * 2. The peer responds with an RST, which tells the local TCP that
 *    the peer host has crashed and rebooted. The socket is closed.
 * 3. There is no response from the peer. The socket is closed.
 *
 * The purpose of this option is to detect if the peer host crashes.
 * Valid only for TCP socket: SocketImpl

当建立TCP链接后,如果应用程序或者上层协议一直不发送数据,或者隔很长一段时间才发送数据,当链接很久没有数据报文传输时就需要通过keepalive机制去确定对方是否在线,链接是否需要继续保持。当超过一定时间没有发送数据时,TCP会自动发送一个数据为空的报文给对方,如果对方回应了报文,说明对方在线,链接可以继续保持,如果对方没有报文返回,则在重试一定次数之后认为链接丢失,就不会释放链接。

控制对闲置连接的检测机制,链接闲置达到7200秒,就开始发送探测报文进行探测。

net.ipv4.tcp_keepalive_time:单位秒,表示发送探测报文之前的链接空闲时间,默认为7200
net.ipv4.tcp_keepalive_intvl:单位秒,表示两次探测报文发送的时间间隔,默认为75
net.ipv4.tcp_keepalive_probes:表示探测的次数,默认9次。

 

三、backlog

  详解:http://jm.taobao.org/2017/05/25/525-1/

OS内核TCP参数一览表:

主要参数
net.ipv4.tcp_keepalive_time:单位秒,表示发送探测报文之前的链接空闲时间,默认为7200。
net.ipv4.tcp_keepalive_intvl:单位秒,表示两次探测报文发送的时间间隔,默认为75。
net.ipv4.tcp_keepalive_probes:表示探测的次数。
net.ipv4.tcp_syncookies:是否开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,1表示开启,0表示关闭,默认为0。
net.ipv4.tcp_tw_reuse:是否开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接,1表示开启,0表示关闭,默认为0。
net.ipv4.tcp_tw_recycle:是否开启TCP连接中TIME-WAIT sockets的快速回收,1表示开启,0表示关闭,默认为0。
net.ipv4.tcp_max_tw_buckets:表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息,默认为180000。
net.ipv4.tcp_fin_timeout:修改系统的TIMEOUT时间。2MSL,

                                         RFC 793中规定MSL为2分钟,实际应用中常用的是30秒
net.ipv4.ip_local_port_range:表示用于向外连接的端口范围。默认为32768 61000(32768到61000)。
net.ipv4.tcp_max_syn_backlog:表示SYN队列的长度,默认为1024。
net.ipv4.tcp_syn_retries:新建TCP连接请求时,尝试发送多少次syn连接请求才决定放弃建立连接,默认值是5。
net.ipv4.tcp_synack_retries:对于远端SYN连接请求,内核会发送SYN+ACK数据包来确认收到了上一个SYN连接请求包,然后等待远端的确认,该值指定了内核会向远端发送多少次SYN+ACK数据包,默认设定值是5。

TCP socket可以通过setsockopt针对单独的socket进行设置:【Java中没有发现可设置的选项】

TCP_KEEPIDLE:对应tcp_keepalive_time。
TCP_KEEPINTVL:对应tcp_keepalive_intvl。
TCP_KEEPCNT:对应tcp_keepalive_probes。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值