Java Socket 的参数选项解读

Java Socket中有很多参数可以选择,这篇文章的目的是沉淀出这些参数的语义和用法,供自己以后查阅。

1、java socket参数选项总览

在JDK1.6中有如下参数选项:

public final static int TCP_NODELAY = 0x0001;
public final static int SO_BINDADDR = 0x000F;
public final static int SO_REUSEADDR = 0x04;
public final static int SO_BROADCAST = 0x0020;
public final static int IP_MULTICAST_IF = 0x10;
public final static int IP_MULTICAST_IF2 = 0x1f;
public final static int IP_MULTICAST_LOOP = 0x12;
public final static int IP_TOS = 0x3;
public final static int SO_LINGER = 0x0080;
public final static int SO_TIMEOUT = 0x1006;
public final static int SO_SNDBUF = 0x1001;
public final static int SO_RCVBUF = 0x1002;
public final static int SO_KEEPALIVE = 0x0008;
public final static int SO_OOBINLINE = 0x1003;

2、public final static int TCP_NODELAY = 0x0001;
要理解这个参数,首先要理解Nagle算法,下面先说说这个Nagle算法

2.1 Nagle算法产生的背景
    当网络传输中存在大量小包传输时,会严重影响传输效率。比如一个包,包头40字节,而真正的内容只有一个字节或者几个字节(典型的有Telnet),这样的传输效率是十分低下的。Nagle算法要解决的就是这种低效率的传输问题。

2.2 Nagle算法的原理
    用通俗的话来说就是,把小包要发送的字节先缓存,当到达一定的阀值的时候再一次性传输。具体算法(伪代码)如下:
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 if
end if
其中MSS为maximum segment size的缩写,是TCP头部的一个字段,表示一个TCP段最大的数据承载量。

2.3 Nagle算法的问题
  在传输大文件的时候,如果使用这个算法,那么会出现明显的延迟现象,因此,在这种情况下,最好是关闭这个算法。

知道了Nagle算法,就知道了TCP_NODELAY这个参数的意义了,如果这个参数被设置为True,那么就是关闭Nagle算法,实现无延迟传输,如果设置为false,则是打开这个算法,会对发送的数据进行缓存。

3、public final static int SO_BINDADDR = 0x000F;
  获取绑定套接字的本地地址(不能仅将此选项“设置”为“得到”,因为套接字是在创建时绑定的,所以本地绑定的地址不可更改)。

4、public final static int SO_REUSEADDR = 0x04;
 
  这个参数表示套接字对端口是否可重用。
  这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息,指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,此时 SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不可能。

一个套接字由相关五元组构成,协议、本地地址、本地端口、远程地址、远程端口。SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口,整个相关五元组还是唯一确定的。所以,重启后的服务程序有可能收到非期望数据。必须慎重使用 SO_REUSEADDR 选项。

5、public final static int SO_BROADCAST = 0x0020;

这个参数选项用来控制广播,目前只有在DatagramSocket里支持。

6、public final static int IP_MULTICAST_IF = 0x10;

用来控制多播的参数选项,目前只有在MulticastSocket里支持


      在MulticastSocket的源代码里有设置多播的方法:

public void setInterface(InetAddress inf) throws SocketException {
    if (isClosed()) {
        throw new SocketException("Socket is closed");
    }
    checkAddress(inf, "setInterface");
    synchronized (infLock) {
        getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
        infAddress = inf;
    }
    }

7、public final static int IP_MULTICAST_IF2 = 0x1f;

这个字段的效果和上面的是一样的,只是扩展支持IPV6

8、public final static int IP_MULTICAST_LOOP = 0x12;

用来设置本地回环接口的多播特性,在MulticastSocket源代码中有相关方法:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8146dee63b32a153663163c48e7aa04d.html