API:java.net.Socket 1.0
setSoTimeout 的底层代码:
getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
public class TimeoutSocketServer {
public static void main(String[] args) {
long startTime = 0L;
try {
ServerSocket serverSocket = new ServerSocket(8080);
serverSocket.setSoTimeout(1000);
while (true) {
startTime = System.currentTimeMillis();
serverSocket.accept();
}
} catch (IOException e) {
long timeout = System.currentTimeMillis() - startTime;
System.out.println(timeout);
e.printStackTrace();
}
}
}
控制台输出:
public class TimeoutSocketServer {
public static void main(String[] args) throws IOException {
long readTime = 0L;
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket socket = serverSocket.accept();
socket.setSoTimeout(1000);
if (socket != null) {
System.out.println("客户端连接上了");
try {
InputStream inStream = socket.getInputStream();
byte[] bytes = new byte[1024];
readTime = System.currentTimeMillis();
while (inStream.read(bytes) != 0) {
System.out.println(Arrays.toString(bytes));
}
} catch (IOException e) {
long timeout = System.currentTimeMillis() - readTime;
System.out.println(timeout);
e.printStackTrace();
}
}
}
}
}
输入命令 telnet 127.0.0.1 8080
启动客户端连接,但是不发送内容。
控制台输出:
通过先构建一个无连接的套接字,然后再使用一个超时来进行连接的方法。
public class TimeoutClient {
public static void main(String[] args) {
Socket socket = new Socket();
long startTime = System.currentTimeMillis();
try {
socket.connect(new InetSocketAddress("127.0.0.1", 8080), 1000);
} catch (IOException e) {
long timeout = System.currentTimeMillis() - startTime;
System.out.println(timeout);
e.printStackTrace();
}
}
}
控制台输出:
当然,我在这个实验中,没有启动服务端,如果客户端不设置 timeout 超时参数的话,连接代码改为下面这段:
socket.connect(new InetSocketAddress("127.0.0.1", 8080));
此时的控制台输出为服务端拒绝连接:
服务端代码
public class Server {
public static void main(String[] args) throws IOException {
long readTime = 0L;
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept();
System.out.println("客户端连接上了");
System.in.read();
}
}
客户端代码
public class TimeoutClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket();
socket.setSoTimeout(3000);
socket.connect(new InetSocketAddress("127.0.0.1", 8080));
long startTime = 0;
try {
InputStream inStream = socket.getInputStream();
startTime = System.currentTimeMillis();
while (inStream.read() != 0) {
System.out.println("接收到了信息");
}
} catch (IOException e) {
long timeout = System.currentTimeMillis() - startTime;
System.out.println(timeout);
e.printStackTrace();
}
}
}
先启动服务端,再启动客户端,控制台输出结果如下:
Socket#setSoTimeout 可以设置读超时时长。如果超过了给定时间,则抛出一个 InterruptedIOException 异常。
ServerSocket#setTimeout 可以设置 ServerSocket#accept 的等待连接的超时时间,如果超过了给定时间,则抛出一个 InterruptedIOException 异常。
Socket#connect 有一个 timeout 参数,可以设置连接超时时长。
InterruptedIOException 时 SocketTimeoutException 的父类。
原文:https://www.cnblogs.com/kendoziyu/p/java-socket-so_timeout.html