码迷,mamicode.com
首页 > 编程语言 > 详细

Java Socket Option

时间:2014-11-06 01:55:53      阅读:294      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   color   ar   os   使用   java   for   

选项

    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在服务器无效的情况下可能会长时间不会关闭。

 

Java Socket Option

标签:style   blog   io   color   ar   os   使用   java   for   

原文地址:http://www.cnblogs.com/yuyutianxia/p/4077717.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!