Socket 和 ServerSocket 中 SoTimeout的作用

服务端,给具体某个Socket 设置socket.setSoTimeout(10000); //毫秒

package org.example;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        final ServerSocket serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress("192.168.0.133", 8888));
        //serverSocket.setSoTimeout(100000);
        final Socket socket = serverSocket.accept();
        //sotimeout的默认值是0,表示不超时
        System.out.println("sotimeout:" + socket.getSoTimeout());
        socket.setSoTimeout(10000); //毫秒
        long t1 = System.currentTimeMillis();
        try {
            socket.getInputStream().read();
        } finally {
            System.out.println(System.currentTimeMillis() - t1);
        }
    }
}

客户端

package org.example;

import java.io.IOException;
import java.net.Socket;

public class client {
    public static void main(String[] args) throws IOException {
        final Socket socket = new Socket("192.168.0.133", 8888);
        long t1 = System.currentTimeMillis();
        try {
            //建立连接以后,客户端始终不发数据,服务端一定会read()超时
            socket.getInputStream().read();
        } finally {
            System.out.println(System.currentTimeMillis() - t1);
        }
    }
}

服务端抛出的异常

sotimeout:0
10001
Exception in thread "main" java.net.SocketTimeoutException: Read timed out
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at java.net.SocketInputStream.read(SocketInputStream.java:224)
	at org.example.Server.main(Server.java:18)

从日志中可以看到10001毫秒后,抛出SocketTimeoutException: Read timed out

客户端抛出异常

10336
Exception in thread "main" java.net.SocketException: Connection reset
	at java.net.SocketInputStream.read(SocketInputStream.java:210)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at java.net.SocketInputStream.read(SocketInputStream.java:224)
	at org.example.client.main(client.java:11)

客户端抛出异常是因为,服务端断开时,给客户端发了RST报文,且客户端在read,所以就抛出了异常。

SoTimeout在JDK源码中的描述,该选项主要作用于ServerSocket.accept() 和 SocketInputStream.read()等。

  /** Set a timeout on blocking Socket operations:
     * <PRE>
     * ServerSocket.accept();
     * SocketInputStream.read();
     * DatagramSocket.receive();
     * </PRE>
     *
     * <P> 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,
     * <B>java.io.InterruptedIOException</B> is raised.  The Socket is
     * not closed in this case.
     *
     * <P> Valid for all sockets: SocketImpl, DatagramSocketImpl
     *
     * @see Socket#setSoTimeout
     * @see ServerSocket#setSoTimeout
     * @see DatagramSocket#setSoTimeout
     */
    @Native public final static int SO_TIMEOUT = 0x1006;

总结一句话:SoTimeout 会影响accept()和read()方法,可以给每个socket都设置,是对象级别的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值