服务端,给具体某个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都设置,是对象级别的。