[Java]Java Socket选项解析

来源:互联网 发布:sql server 分组排序 编辑:程序博客网 时间:2024/05/16 16:19
Java里,Socket的Option由java.net.SocketOptions这个接口声明,如下所示:
@Native public final static int TCP_NODELAY = 0x0001;@Native public final static int SO_BINDADDR = 0x000F;@Native public final static int SO_REUSEADDR = 0x04;@Native public final static int SO_BROADCAST = 0x0020;@Native public final static int IP_MULTICAST_IF = 0x10;@Native public final static int IP_MULTICAST_IF2 = 0x1f;@Native public final static int IP_MULTICAST_LOOP = 0x12;@Native public final static int IP_TOS = 0x3;@Native public final static int SO_LINGER = 0x0080;@Native public final static int SO_TIMEOUT = 0x1006;@Native public final static int SO_SNDBUF = 0x1001;@Native public final static int SO_RCVBUF = 0x1002;@Native public final static int SO_KEEPALIVE = 0x0008;@Native public final static int SO_OOBINLINE = 0x1003;
它们是什么意思呢?下面对每项进行解析。

1. TCP_NODELAY

Disable Nagle's algorithm for this connection. Written data to the network is not buffered pending acknowledgement of previously written data.
纳格算法(Nagle's algorithm)的工作方式是合并(coalescing)一定数量的输出资料后一次送出。当某application不断地发送小单位的数据时,tcp会缓存一定量的数据再进行发送。具体算法如下所示:
if there is new data to send  if the window size >= MSS and available data is >= MSS    send complete MSS segment now  else    if there is unconfirmed data still in the pipe      enqueue data in the buffer until an acknowledge is received    else      send data immediately    end if  end ifend if
注:按照算法,是尚未收到前一次ack或未达到指定累积大小前缓存接下来的数据。TCP专用综上,TCP_NODELAY如果为true,那么数据就不进行缓存(等待上一个ack或达到指定累积大小)。

2. SO_BINDADDR

Fetch the local address binding of a socket (this option cannot be "set" only "gotten", since sockets are bound at creation time, and so the locally bound address cannot be changed). The default local address of a socket is INADDR_ANY, meaning any local address on a multi-homed host. A multi-homed host can use this option to accept connections to only one of its addresses (in the case of a ServerSocket or DatagramSocket), or to specify its return address to the peer (for a Socket or DatagramSocket). The parameter of this option is an InetAddress.
如注释所述,这个Option有如下特点:
  1. 只能通过getOption读取,不能通过setOption设置。因为地址绑定发生在Socket初始化的时候,
    后面就不能更改了。
  2. 默认值为INADDR_ANY。如果用于ServerSocket,即在“multi-homed host(同一主机上有多个网
    络地址)”的情况下,socket接收所有网络接口发过来的数据。设置了指定的Address,那么就接收指定
    接口的数据;如果用于Socket,设置了指定的Address表示向该地址发送数据。
  3. 该选项值的类型为InetAddress

3. SO_REUSEADDR

Sets SO_REUSEADDR for a socket. This is used only for MulticastSockets in java, and it is set by default for MulticastSockets.
仅用于DatagramSocket(UDP)。一般来说,一个端口释放后会等待两分钟之后才能再被使用,
SO_REUSEADDR是让端口释放后立即就可以被再次使用。
SO_REUSEADDR可以用在以下四种情况下。 (摘自《Unix网络编程》卷一,即UNPv1) 1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启
动程序的socket2要占用该地址和端口,你的程序就要用到该选项。 2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但
每实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可
以试这种情况。 3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个soc
kt绑定的ip地址不同。这和2很相似,区别请看UNPv1。 4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的
多播,不用于TCP。

4. SO_BROADCAST

Sets SO_BROADCAST for a socket. This option enables and disables the ability of the process to send broadcast messages. It is supported for only datagram sockets and only on networks that support the concept of a broadcast message (e.g. Ethernet, token ring, etc.), and it is set by default for DatagramSockets.
SO_BROADCAST决定了socket是否可以发广播。仅用于支持广播的网络。

5. IP_MULTICAST_IF

Set which outgoing interface on which to send multicast packets. Useful on hosts with multiple network interfaces, where applications want to use other than the system default. Takes/returns an InetAddress.
用于确定组播(multicast)的网络接口。选项值类型为InetAddress。注:关于单播、广播和组播的概念,可参考http://blog.csdn.net/dabing69221/article/details/17286441

6. IP_MULTICAST_IF

同#IP_MULTICAST_IF,但是可以设IPV4或IPV6地址。

7. IP_MULTICAST_LOOP

This option enables or disables local loopback of multicast datagrams. This option is enabled by default for Multicast Sockets.
这个选项用于组播。其中“local loopback”的意思是组播包会同时发送给自己(即发送方可以收到自己发出去的数据)。

8. IP_TOS

This option sets the type-of-service or traffic class field in the IP header for a TCP or UDP socket.
用于设置IP包TOS部分的值。UDP可以在bind之后任意更改设置,TCP在bind前设置。一般来说,TOS值有以下三种:
 IPTOS_LOWCOST (0x02) 成本优先(?) IPTOS_RELIABILITY (0x04) 可靠性优先 IPTOS_THROUGHPUT (0x08) 吞吐量优先 IPTOS_LOWDELAY (0x10) 延时优先

9. SO_LINGER

Specify a linger-on-close timeout. This option disables/enables immediate return from a close() of a TCP Socket. Enabling this option with a non-zero Integer timeout means that a close() will block pending the transmission and acknowledgement of all data written to the peer, at which point the socket is closed gracefully. Upon reaching the linger timeout, the socket is closed forcefully, 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.
设置了一个大于0的值给SO_LINGER,表示当关闭这个TCP socket时,如果发送队列里还有数据,
那么堵塞等待一段时间( linger interval)。如果超时了,那么强制关闭连接。设置等于0的值表示直接强制关闭连接。超时上限为65535。

10. SO_TIMEOUT

Set a timeout on blocking Socket operations: ServerSocket.accept(); SocketInputStream.read(); DatagramSocket.receive(); The option must be set prior to entering a blocking operation to take effect. If the timeout expires and the operation would continue to block, java.io.InterruptedIOException is raised. The Socket is not closed in this case.
SO_TIMEOUT选项用于对read()操作设置timeout,单位为毫秒。当timeout发生时,会抛出
InterruptedIOException。设置不大于0的值会令read()操作永远堵塞。

11. SO_SNDBUF

Set a hint the size of the underlying buffers used by the platform for outgoing network I/O. When used in set, this is a suggestion to the kernel from the application about the size of buffers to use for the data to be sent over the socket. When used in get, this must return the size of the buffer actually used by the platform when sending out data on this socket.
设置SO_SNDBUF表示向内核建议socket发送缓冲区的大小。获取SO_SNDBUF一定返回实际发送缓冲区
的大小。单位字节。

12. SO_RCVBUF

Set a hint the size of the underlying buffers used by the platform for incoming network I/O. When used in set, this is a suggestion to the kernel from the application about the size of buffers to use for the data to be received over the socket. When used in get, this must return the size of the buffer actually used by the platform when receiving in data on this socket.
设置SO_RCVBUF表示向内核建议socket接收缓冲区的大小。获取SO_RCVBUF一定返回实际接收缓冲区
的大小。单位字节。

13. SO_KEEPALIVE

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.
SO_KEEPALIVE启用时,当tcp连接中没有数据流动超过2小时时,系统主动发送一个keepalive探寻包(probe)给
对方,对方必须响应这个包。收到ack的时候表示连接正常。满足以下条件时视为连接关闭:
  1. 对方返回了RST
  2. 对方没有任何返回

14. SO_OOBINLINE

When the OOBINLINE option is set, any TCP urgent data received on the socket will be received through the socket input stream. When the option is disabled (which is the default) urgent data is silently discarded.
该选项默认disable,当enable时,表示urgent data直接在接收方read()操作中返回(和普通数据混在一起),否则接收方直接忽略该数据。

查看原文:http://legendmohe.net/2017/07/14/javajava-socket%e9%80%89%e9%a1%b9%e8%a7%a3%e6%9e%90/