文章目录
ServerSocket
-
ServerSocket
只负责接收连接,用于产生Socket
。 -
ServerSocket
的构造方法,port
指定服务器要绑定的端口(即监听的端口),backlog
指定客户连接请求队列的长度(默认50),bindAddr
指定服务器要绑定的IP地址,一旦服务器与特定的端口绑定,有些选项就不能再改变了public ServerSocket() throws IOException public ServerSocket(int port) throws IOException public ServerSocket(int port, int backlog) throws IOException public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
-
如果把构造方法的参数
port
设为0,表示由操作系统来为服务器分配一个任意可用的端口(匿名端口)。默认构造方法创建ServerSocket
不与任何端口绑定,需要手动通过bind()方法与特定端口绑定。默认构造方法的用途是,允许服务器在绑定特定端口之前,先设置ServerSocket
的一些选项。因为一旦服务器与特定端口绑定,有些选项就不能再改变了。例如SO_REUSEADDR
选项必须在绑定端口之前设置。@Test public void testPort() throws Exception { //绑定具体端口 ServerSocket ss = new ServerSocket(3000); //输出:3000 System.out.println(ss.getLocalPort()); ss.close(); //手动绑定 ss = new ServerSocket(); ss.bind(new InetSocketAddress(4000)); //输出:4000 System.out.println(ss.getLocalPort()); ss.close(); //匿名端口 ss = new ServerSocket(0); //输出:56740 (每次输出都不一样) System.out.println(ss.getLocalPort()); ss.close(); }
-
如果运行时无法绑定80端口,会抛
BindException
异常,它是IOException
的子类,BindException
一般是由以下原因造成
- 端口已经被其他服务器进程占用- 在某些操作系统中,如果没有以超级管理员的身份来运行服务器程序,那么操作系统不允许服务器绑定到1-1023之间的端口。
@Test public void testBindException()throws Exception{ ServerSocket ss = new ServerSocket(3000); ServerSocket ss2 = new ServerSocket(3000); }
backlog
-
当服务器进程运行时,可能会同时监听到多个客户的连接请求。管理客户连接请求的任务是由操作系统来完成的。操作系统把这些连接请求存储在一个先进先出的队列中。许多操作系统限定了队列的最大长度,一般为50。当队列中的连接请求达到了队列的最大容量时,服务器进程所在的主机会拒绝连接新的连接请求。只有当服务器进程通过
ServerSocket
的accept()方法从队列中取出连接请求,使队列腾出空位时,队列才能继续加入新的连接请求。accept()方法为下一个传入的连接请求创建Socket
实例,并将已成功连接的Socket
实例返回给服务器端套接字。如果没有连接请求等待,accept()方法将阻塞等待,直到有新的连接请求到来或超时。对于客户端进程,如果它发出的连接请求被加入到服务器的队列中,就意味着客户与服务器的连接请求被服务器拒绝,Socket
构造方法会抛出ConnectionException
。