在使用ServerSocket对象绑定一个端口后,操作系统就会为这个端口分配一个先进先出的队列(这个队列长度的默认值一般是50),这个队列用于保存未处理的客户端请求,因此叫请求队列。而ServerSocket类的accept方法负责从这个队列中读取未处理的客户端请求。如果请求队列为空,accept则处于阻塞状态。每当客户端向服务端发来一个请求,服务端会首先将这个客户端请求保存在请求队列中,然后accept再从请求队列中读取。这也可以很好地解释为什么上面的代码在还未执行到accept方法时,仍然可以接收一定数量的客户端请求。如果请求队列中的客户端请求数达到请求队列的最大容量时,服务端将无法再接收客户端请求。如果这时客户端再向服务端发请求,客户端将会抛出一个SocketException异常。
ServerSocket类有两个构造方法可以使用backlog参数重新设置请求队列的长度。在以下几种情况,仍然会采用操作系统限定的请求队列的最大长度:
backlog的值小于等于0。
backlog的值大于操作系统限定的请求队列的最大长度。
在ServerSocket构造方法中未设置backlog参数。
下面积代码演示了请求队列的一些特性,请求队列长度通过命令行参数传入SetRequestQueue。
package server;
import java.net.*;
class TestRequestQueue
{
public static void main(String[] args) throws Exception
{
for (int i = 0; i < 10; i++)
{
Socket socket = new Socket("localhost", 1234);
socket.getOutputStream().write(1);
System.out.println("已经成功创建第" + String.valueOf(i + 1) + "个客户端连接!");
}
}
}
public class SetRequestQueue
{
public static void main(String[] args) throws Exception
{
if (args.length == 0)
return;
int queueLength = Integer.parseInt(args[0]);
ServerSocket serverSocket = new S