选项

    public final static int TCP_NODELAY = 0x0001;
public final static int SO_REUSEADDR = 0x04;
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;

一。TCP_NODELAY

在默认false下,客户端向服务器发送数据时,会根据数据包的大小决定是否立即发送。当数据包中的数据很少时,如只有1个字节,而数据包的头却有几十个字

节(IP头+TCP头)时,系统会在发送之前先将较小的包合并到软大的包后,一起将数据发送出去。在发送下一个数据包时,系统会等待服务器对前一个数据包

的响应,当收到服务器的响应后,再发送下一个数据包,这就是所谓的Nagle算法

二。SO_REUSEADDR

如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息, 抛出“Address

already in use: JVM_Bind”。如果你的服务程序停止后想立即重启,不等60秒,而新套接字依旧 使用同一端口,此时 SO_REUSEADDR 选项非常有用。

在Windows平台,多个Socket新建立对象可以绑定在同一个端口上,这些新连接是非TIME_WAIT状态的。这样做并没有多大意义。

在Linux平台,只有TCP状态位于 TIME_WAIT ,才可以重用 端口。这才是正确的行为。

publicclass Test {

    public static void main(String[] args) {

        try {

            ServerSocket socket1 = new ServerSocket();
ServerSocket socket2 = new ServerSocket();
socket1.setReuseAddress(true);
socket1.bind(new InetSocketAddress("127.0.0.1", 8899));
System.out.println("socket1.getReuseAddress():" + socket1.getReuseAddress());
socket2.setReuseAddress(true);
socket2.bind(new InetSocketAddress("127.0.0.1", 8899));
System.out.println("socket2.getReuseAddress():" + socket1.getReuseAddress()); } catch (Exception e) {
e.printStackTrace();
}
}
}

使用SO_REUSEADDR选项时有两点需要注意:

1.  必须在调用bind方法之前使用setReuseAddress方法来打开SO_REUSEADDR选项。因此,要想使用SO_REUSEADDR选项,就不能通过Socket

类的构造方法来绑定端口。

2.  必须将绑定同一个端口的所有的Socket对象的SO_REUSEADDR选项都打开才能起作用。socket1和socket2都使用了setReuseAddress方法打开

了各自的SO_REUSEADDR选项。

在Windows平台表现的特点是不正确的:

socket1.getReuseAddress():true
socket2.getReuseAddress():true

在Linux平台表现的特点是正确的: 因为第一个连接不是TIME_WAIT状态的,第二个连接就不能使用8899端口

socket1.getReuseAddress():true
java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
at java.net.ServerSocket.bind(ServerSocket.java:328)
at java.net.ServerSocket.bind(ServerSocket.java:286)
at com.Test.main(Test.java:15)

三。SO_LINGER

这个Socket选项可以影响close方法的行为。在默认情况下,当调用close方法后,将立即返回;如果这时仍然有未被送出的数据包,那么这些数据包将

被丢弃。

  如果将linger参数设为一个正整数n时(n的值最大是65,535),在调用close方法后,将最多被阻塞n秒。在这n秒内,系统将尽量将未送出的数

据包发送出去;如果超过了n秒,如果还有未发送的数据包,这些数据包将全部被丢弃;而close方法会立即返回。

  如果将linger设为0,和关闭SO_LINGER选项的作用是一样的。

如果底层的Socket实现不支持SO_LINGER都会抛出SocketException例外。

  当给linger参数传递负数值时,setSoLinger还会抛出一个IllegalArgumentException例外。可以通过getSoLinger方法得到延迟关闭的时间,如果

返回-1,则表明SO_LINGER是关闭的。例如,下面的代码将延迟关闭的时间设为1分钟:

if(socket.getSoLinger() == -1) socket.setSoLinger(true, 60);

四。SO_TIMEOUT

  可以通过这个选项来设置读取数据超时。当输入流的read方法被阻塞时,如果设置timeout,那么系统在等待了timeout毫秒后会抛出

InterruptedIOException。在抛出后,输入流并未关闭,你可以继续通过read方法读取数据。

如果将timeout设为0,就意味着read将会无限等待下去,直到服务端程序关闭这个Socket。这也是timeout的默认值。

五。SO_SNDBUF

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

setSendBufferSize方法来重新设置缓冲区的大小。但最好不要将输出缓冲区设得太小,否则会导致传输数据过于频繁,从而降低网络传输的效率。

六。SO_RCVBUF

The value of SO_RCVBUF is also used to set the TCP receive window that is advertized to the remote peer. Generally, the window size

can be modified at any time when a socket is connected. However, if a receive window larger than 64K is required then this must be

requested before the socket is connected to the remote peer. There are two cases to be aware of:

  1. For sockets accepted from a ServerSocket, this must be done by calling ServerSocket.setReceiveBufferSize(int) before the

ServerSocket is bound to a local address.

2. For client sockets, setReceiveBufferSize() must be called before connecting the socket to its remote peer.

七。SO_KEEPALIVE

  如果将这个选项打开,客户端Socket每隔段的时间就会利用空闲的连接向服务器发送一个数据包。这个数据包并没有其它的作用,只是为了检

测一下服务器是否仍处于活动状态。如果服务器未响应这个数据包,那么客户端Socket将关闭。

  如果将这个选项关闭,客户端Socket在服务器无效的情况下可能会长时间不会关闭。

八。SO_OOBINLINE

  如果这个Socket选项打开,可以通过Socket类的sendUrgentData方法向服务器发送一个单字节的数据。这个单字节数据并不经过输出缓冲区,

而是立即发出。必须在客户端和服务端程序同时使用setOOBInline方法打开这个选项,否则无法命名用sendUrgentData来发送数据。

  虽然在客户端并不是使用OutputStream向服务器发送数据,但在服务端程序中这个单字节的数据是和其它的普通数据混在一起的。因此,在服

务端程序中并不知道由客户端发过来的数据是由OutputStream还是由sendUrgentData发过来的。

  Note, only limited support is provided for handling incoming urgent data. In particular, no notification of incoming urgent data

is provided and there is no capability to distinguish between normal data and urgent data unless provided by a higher level protocol.

public class Server{
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(1234);
System.out.println("服务器已经启动,端口号:1234");
while (true) {
Socket socket = serverSocket.accept();
socket.setOOBInline(true);
InputStream in = socket.getInputStream();
InputStreamReader inReader = new InputStreamReader(in);
BufferedReader bReader = new BufferedReader(inReader);
System.out.println(bReader.readLine());
System.out.println(bReader.readLine());
socket.close();
}
}
}
public class Client{
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 1234);
socket.setOOBInline(true);
OutputStream out = socket.getOutputStream();
OutputStreamWriter outWriter = new OutputStreamWriter(out);
outWriter.write(67); // 向服务器发送字符"C"
outWriter.write("hello world\r\n");
socket.sendUrgentData(65); // 向服务器发送字符"A"
socket.sendUrgentData(322); // 向服务器发送字符"B"
outWriter.flush();
socket.sendUrgentData(214); // 向服务器发送汉字”中”
socket.sendUrgentData(208);
socket.sendUrgentData(185); // 向服务器发送汉字”国”
socket.sendUrgentData(250);
socket.close();
}
}

虽然sendUrgentData(int date)的参数data是int类型,但只有这个int类型的低字节被发送,其它的三个字节被忽略。

sendUrgentData(322)时实际发送的是66,所以输出B

服务器已经启动,端口号:1234
ABChello world
中国

输出结果说明使用sendUrgentData方法发送数据后,系统会立即将这些数据发送出去;而使用write发送数据,必须要使用flush方法才会真正发送数据。

Java Socket Option的更多相关文章

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

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

  2. 使用Java Socket手撸一个http服务器

    原文连接:使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomc ...

  3. Java Socket Timeout 总结

    原文出处:囚兔 摘要: Java的网络编程Socket常常用于各种网络工具,比如数据库的jdbc客户端,redis客户端jedis,各种RPC工具java客户端,这其中存在一些参数来配置timeout ...

  4. java socket 的参数选项解读

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

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

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

  6. JAVA通信系列一:Java Socket技术总结

    本文是学习java Socket整理的资料,供参考. 1       Socket通信原理 1.1     ISO七层模型 1.2     TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...

  7. JAVA Socket 编程学习笔记(二)

    在上一篇中,使用了 java Socket+Tcp/IP  协议来实现应用程序或客户端--服务器间的实时双向通信,本篇中,将使用 UDP 协议来实现 Socket 的通信. 1. 关于UDP UDP协 ...

  8. JAVA Socket 编程学习笔记(一)

    1. Socket 通信简介及模型 Java Socket 可实现客户端--服务器间的双向实时通信.java.net包中定义的两个类socket和ServerSocket,分别用来实现双向连接的cli ...

  9. Java Socket Server的演进 (一)

    最近在看一些网络服务器的设计, 本文就从起源的角度介绍一下现代网络服务器处理并发连接的思路, 例子就用java提供的API. 1.单线程同步阻塞式服务器及操作系统API 此种是最简单的socket服务 ...

随机推荐

  1. Xamarin.iOS项目编译提示Could not AOT the assembly

    Xamarin.iOS项目编译提示Could not AOT the assembly 错误信息:Could not AOT the assembly **************.dll 这个错误是 ...

  2. Hadoop_10_12虚拟机01_虚拟机NAT方式联网【自己的亲测笔记】

      NAT方式 1.查看网络信息--ifconfig(同windows中的ipconfig相同) 主要关注的是第三行内容,分别是Ip地址.广播地址.子网掩码 2.安装完系统后需要配置三个地方--IP地 ...

  3. [Unity3D]脚本中Start()和Awake()的区别

    Unity3D初学者经常把Awake和Start混淆. 简单说明一下,Awake在MonoBehavior创建后就立刻调用,Start将在MonoBehavior创建后在该帧Update之前,在该Mo ...

  4. BZOJ3784 : 树上的路径

    树的点分治,在分治的时候将所有点到根的距离依次放入一个数组q中. 对于一棵子树里的点,合法的路径一定是q[L]..q[R]的某个数加上自己到重心的距离. 定义五元组(v,l,m,r,w),表示当前路径 ...

  5. clumsy 0.1 测试工具(延迟\掉包\节流\重发\乱序\篡改)

    clumsy : http://jagt.github.io/clumsy/可以模拟以下几种场景: 延迟(Lag),把数据包缓存一段时间后再发出,这样能够模拟网络延迟的状况. 掉包(Drop),随机丢 ...

  6. 【BZOJ】2929: [Poi1999]洞穴攀行(最大流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2929 题意描述不清..搞得我wa了一发.. 应该是,有1和n的点的边容量都为1,其余随便... 然后 ...

  7. HDU 4648 Magic Pen 6

    题目链接 6Y什么水平.. #include <cstdio> #include <cstring> #include <string> #include < ...

  8. BZOJ3809: Gty的二逼妹子序列

    Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题.   对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数.   为了方 ...

  9. ext4 文件系统的一些记录

    https://www.kernel.org/doc/Documentation/filesystems/ext4.txt ext4 权威说明 http://computer-forensics.sa ...

  10. 【Linux】linux常用基本命令(转)

    (转自:http://blog.csdn.net/xiaoguaihai/article/details/8705992) Linux中许多常用命令是必须掌握的,这里将我学linux入门时学的一些常用 ...