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源代码中有相关方法:

/**
* Disable/Enable local loopback of multicast datagrams
* The option is used by the platform's networking code as a hint
* for setting whether multicast data will be looped back to
* the local socket.
*
* <p>Because this option is a hint, applications that want to
* verify what loopback mode is set to should call
* {@link #getLoopbackMode()}
* @param disable <code>true</code> to disable the LoopbackMode
* @throws SocketException if an error occurs while setting the value
* @since 1.4
* @see #getLoopbackMode
*/
public void setLoopbackMode(boolean disable) throws SocketException {
getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
}

9、public final static int IP_TOS = 0x3;

这个参数是用来控制IP头中的TOS字段的,是用来控制和优化IP包的路径的,在Socket源代码里有一个设置的方法:

/**
* Sets traffic class or type-of-service octet in the IP
* header for packets sent from this Socket.
* As the underlying network implementation may ignore this
* value applications should consider it a hint.
*
* <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
* 255</code> or an IllegalArgumentException will be thrown.
* <p>Notes:
* <p> For Internet Protocol v4 the value consists of an octet
* with precedence and TOS fields as detailed in RFC 1349. The
* TOS field is bitset created by bitwise-or'ing values such
* the following :-
* <p>
* <UL>
* <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
* <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
* <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
* <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
* </UL>
* The last low order bit is always ignored as this
* corresponds to the MBZ (must be zero) bit.
* <p>
* Setting bits in the precedence field may result in a
* SocketException indicating that the operation is not
* permitted.
* <p>
* As RFC 1122 section 4.2.4.2 indicates, a compliant TCP
* implementation should, but is not required to, let application
* change the TOS field during the lifetime of a connection.
* So whether the type-of-service field can be changed after the
* TCP connection has been established depends on the implementation
* in the underlying platform. Applications should not assume that
* they can change the TOS field after the connection.
* <p>
* For Internet Protocol v6 <code>tc</code> is the value that
* would be placed into the sin6_flowinfo field of the IP header.
*
* @param tc an <code>int</code> value for the bitset.
* @throws SocketException if there is an error setting the
* traffic class or type-of-service
* @since 1.4
* @see #getTrafficClass
*/
public void setTrafficClass(int tc) throws SocketException {
if (tc < 0 || tc > 255)
throw new IllegalArgumentException("tc is not in range 0 -- 255"); if (isClosed())
throw new SocketException("Socket is closed");
getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
}

从源代码的注释看,TOS设置了是否生效,和底层的操作系统的实现有关。应用程序无法保证TOS的变更会对socket连接产生影响。个人认为,TOS在一般情况下用不到。

10、public final static int SO_LINGER = 0x0080;

先看Socket源代码:

/**
* Enable/disable SO_LINGER with the specified linger time in seconds.
* The maximum timeout value is platform specific.
*
* The setting only affects socket close.
*
* @param on whether or not to linger on.
* @param linger how long to linger for, if on is true.
* @exception SocketException if there is an error
* in the underlying protocol, such as a TCP error.
* @exception IllegalArgumentException if the linger value is negative.
* @since JDK1.1
* @see #getSoLinger()
*/
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));
}
}

这个字段对Socket的close方法产生影响,当这个字段设置为false时,close会立即执行并返回,如果这时仍然有未被送出的数据包,那么这些数据包将被丢弃。如果设置为True时,有一个延迟时间可以设置。这个延迟时间就是close真正执行所有等待的时间,最大为65535。

11、public final static int SO_TIMEOUT = 0x1006;

/**
* Enable/disable SO_TIMEOUT with the specified timeout, in
* milliseconds. With this option set to a non-zero timeout,
* a read() call on the InputStream associated with this Socket
* will block for only this amount of time. If the timeout expires,
* a <B>java.net.SocketTimeoutException</B> is raised, though the
* Socket is still valid. The option <B>must</B> be enabled
* prior to entering the blocking operation to have effect. The
* timeout must be > 0.
* A timeout of zero is interpreted as an infinite timeout.
* @param timeout the specified timeout, in milliseconds.
* @exception SocketException if there is an error
* in the underlying protocol, such as a TCP error.
* @since JDK 1.1
* @see #getSoTimeout()
*/
public synchronized void setSoTimeout(int timeout) throws SocketException {
if (isClosed())
throw new SocketException("Socket is closed");
if (timeout < 0)
throw new IllegalArgumentException("timeout can't be negative"); getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
}

这个参数用来控制客户端读取socket数据的超时时间,如果timeout设置为0,那么就一直阻塞,否则阻塞直到超时后直接抛超时异常。

12、public final static int SO_SNDBUF = 0x1001;

在默认情况下,输出流的发送缓冲区是8096个字节(8K)。这个值是Java所建议的输出缓冲区的大小。如果这个默认值不能满足要求,可以用setSendBufferSize方法来重新设置缓冲区的大小。

13、public final static int SO_RCVBUF = 0x1002;

在默认情况下,输入流的接收缓冲区是8096个字节(8K)。这个值是Java所建议的输入缓冲区的大小。如果这个默认值不能满足要求,可以用setReceiveBufferSize方法来重新设置缓冲区的大小。

14、public final static int SO_KEEPALIVE = 0x0008;

如果将这个参数这是为True,客户端每隔一段时间(一般不少于2小时)就像服务器发送一个试探性的数据包,服务器一般会有三种回应:

1、服务器正常回一个ACK,这表明远程服务器一切OK,那么客户端不会关闭连接,而是再下一个2小时后再发个试探包。

2、服务器返回一个RST,这表明远程服务器挂了,这时候客户端会关闭连接。

3、如果服务器未响应这个数据包,在大约11分钟后,客户端Socket再发送一个数据包,如果在12分钟内,服务器还没响应,那么客户端Socket将关闭。

15、public final static int SO_OOBINLINE = 0x1003;

如果这个Socket选项打开,可以通过Socket类的sendUrgentData方法向服务器发送一个单字节的数据。这个单字节数据并不经过输出缓冲区,而是立即发出。虽然在客户端并不是使用OutputStream向服务器发送数据,但在服务端程序中这个单字节的数据是和其它的普通数据混在一起的。因此,在服务端程序中并不知道由客户端发过来的数据是由OutputStream还是由sendUrgentData发过来的。

java socket 的参数选项解读的更多相关文章

  1. java socket 的参数选项解读(转)

    java socket中有很多参数可以选择,这篇博客的目的是沉淀出这些参数的语义和用法,供自己以后查阅. 1.java socket参数选项总览 在JDK1.6中有如下参数选项: 1 public f ...

  2. Java Socket重要参数讲解

    (转自http://www.cnblogs.com/ggjucheng/archive/2012/01/06/2314679.html) ( http://docs.oracle.com/javase ...

  3. Java 6 JVM参数选项大全(中文版)

    原文来自: http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm 本文是基于最新的SUN官方文档Java SE 6 Hotsp ...

  4. Socket: Java Socket 几个重要的TCP/IP选项解析(转)

    Socket选择可以指定Socket类发送和接受数据的方式.在JDK1.4中共有8个Socket选择可以设置.这8个选项都定义在java.net.SocketOptions接口中.定义如下: publ ...

  5. Java - Java 命令行简介: 选项, 属性, 参数

    概述 简单介绍一下 java 命令行相关的参数及属性 1. java 命令行 基本 命令 > java <mainClass> 描述 执行 Java 类 需要准备好编译完成的 mai ...

  6. java socket API

    java.net类 Socket java.lang.Object java.net.Socket 直接已知子类: SSLSocket public class Socketextends Objec ...

  7. java Socket用法详解(转)

    在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...

  8. Java Socket 学习笔记

    TCP协议的Socket编程 Socket:英文中的意思是插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket.Java中所有关于网络编程的类都 ...

  9. Java Socket与操作系统的关系

    Socket与操作系统有什么关系呢?请细读下文 简介 TCP简介 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议 ...

随机推荐

  1. 如何使用google地图的api(整理)

    如何使用google地图的api(整理) 一.总结 一句话总结:直接用script标签引google地图api即可. 1.如何使用google地图的api? 页面引用javascript文件<s ...

  2. php 面试题一(看视频的学习量比网上瞎转悠要清晰和明了很多)(看视频做好笔记)(注重复习)

    php 面试题一(看视频的学习量比网上瞎转悠要清晰和明了很多)(看视频做好笔记)(注重复习) 一.总结 1.无线分类的本质是树(数据结构)(数的话有多种储存结构可以实现,所以对应的算法也有很多),想到 ...

  3. 超链接a的download属性 实现文件下载功能

    今天做项目遇到一个要点击按钮下载文件的功能. 百度之 知道了a的download属性.这是HTML5的新特性.主要功能是实现下载功能.主要语法是 <a href="url" ...

  4. MHA 一主两从搭建-keepalived-手动切换

    环境介绍:主机名 IP MHA角色 MySQL角色node1 192.168.56.26 Node MySQL Master node2 192.168.56.27 Node MySQL Master ...

  5. sublime text2 基本配置及结合Python 环境

    参考: http://www.cnblogs.com/figure9/p/sublime-text-complete-guide.html http://www.zhihu.com/question/ ...

  6. LDR: LdrpWalkImportDescriptor() failed to probe C:\WINDOWS\system32\opencv_core243d.dll for its manifest, ntstatus 0xc0150002

    LDR: LdrpWalkImportDescriptor() failed to probe C:\WINDOWS\system32\opencv_core243d.dll for its mani ...

  7. [CSS] No selectable effect

    .noselect { -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Chrome/Safar ...

  8. HOOK API入门之Hook自己程序的MessageBoxW(简单入门)

    说到HOOK,我看了很多的资料和教程,无奈就是学不会HOOK,不懂是我的理解能力差,还是你们说的 不够明白,直到我看了以下这篇文章,终于学会了HOOK: http://blog.sina.com.cn ...

  9. js进阶正则表达式6转义字符(加\转义)(.符号)(|符号)

    js进阶正则表达式6转义字符(加\转义)(.符号)(|符号) 一.总结 转义字符:{} () / $ # & * . ....... //3.特殊字符,都要加转义\ 点符号:var reg2= ...

  10. 【u003】计算概率

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小明有n个长度不一的小木棍,这些木棍的长度都是正整数.小明的父亲想和小明做一个游戏.他规定一个整数长度 ...