第三章 ServerSpcket用法详解
构造ServerSocket
ServerSocket的构造方法如下:
1 ServerSocket() 2 //Creates an unbound server socket. 3 4 ServerSocket(int port) 5 //Creates a server socket, bound to the specified port. 6 7 ServerSocket(int port, int backlog) 8 //Creates a server socket and binds it to the specified local port number, with the 9 //specified backlog. 10 11 ServerSocket(int port, int backlog, InetAddress bindAddr) 12 //Create a server with the specified port, listen backlog, and local IP address to 13 //bind to.
参数port指定服务器需要绑定的端口(监听端口),参数backlog指定客户连接请求队列的长度,参数bindAddr指定服务器需要绑定的IP地址。
参数port设为0时,由系统自动分配端口。
当队列中的连接请求达到了队列的最大容量时,服务器进程所在的主机会拒绝新的连接请求。当服务器通过ServerSocket.accept()方法从队列取出连接请求时,队列腾出空位,新的连接请求加入队列。
对于客户机进程,如果他发出的连接请求被加入到服务器队列,则说明连接成功,客户机Socket正常返回,否则抛出ConnectionException异常。
以下建立Server与Client代码进行验证:
1 //Server代码 2 package Section_03; 3 4 import java.io.IOException; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 8 public class Server { 9 private int port=8001; 10 private ServerSocket serverSocket; 11 12 public Server() throws IOException{ 13 serverSocket = new ServerSocket(port,3); 14 System.out.println("服务器启动!"); 15 } 16 17 public void service(){ 18 while(true){ 19 Socket socket=null; 20 try{ 21 socket=serverSocket.accept(); 22 System.out.println("新的连接 "+socket.getInetAddress()+":"+socket.getPort()); 23 }catch(IOException e){ 24 e.printStackTrace(); 25 }finally{ 26 try{ 27 if(socket!=null){ 28 socket.close(); 29 } 30 }catch(IOException e){ 31 e.printStackTrace(); 32 } 33 } 34 } 35 } 36 public static void main(String[] args) throws IOException, InterruptedException { 37 // TODO Auto-generated method stub 38 Server server = new Server(); 39 Thread.sleep(60000*10); 40 server.service(); 41 } 42 43 } 44 45 46 47 48 //Client代码 49 package Section_03; 50 51 import java.io.IOException; 52 import java.net.Socket; 53 import java.net.UnknownHostException; 54 55 public class Client { 56 57 public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException { 58 // TODO Auto-generated method stub 59 int length=100; 60 String host="localhost"; 61 int port=8001; 62 63 Socket[] sockets=new Socket[length]; 64 for(int i=0;i<length;i++){ 65 sockets[i]=new Socket(host,port); 66 System.out.println("第"+(i+1)+"次连接成功!"); 67 } 68 Thread.sleep(3000); 69 for(int i=0;i<length;i++){ 70 sockets[i].close(); 71 72 } 73 } 74 75 }
因为Server启动10分钟后才执行service方法,故10分钟之前都不会从队列取出连接请求。当队列达到三个后便拒绝后面新的请求。Client执行效果如下:
第1次连接成功!
第2次连接成功!
第3次连接成功!
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Section_03.Client.main(Client.java:17)
使用无参构造函数
ServerSocket有一个无构造函数,它的作用时运行服务器在绑定端口前,先设置一些选项,再通过bind方法绑定端口。因为一旦绑定端口后,有些选项无法改变。
如下代码:
ServerSocket serverSocket=new ServerSocket(8000);
serverSocket.setReuserAddress(true);
第二行代码是无效的。应该改为:
ServerSocket serverSocket=new ServerSocket();
serverSocket.setReuserAddress(true);
serverSocket.bind(new InetSocketAddress(8000));
本章未完待续……