标签:
网络服务器,顾名思义是一个可以接受连接的host,我们要实现的网络服务器类是一个
1.能够实现多个连接
2.仅仅通过继承或实现网络服务器类(或接口)的处理就能实现不同的连接功能
3.当服务器关闭时,已有建立的私有连接不被中断,但服务器不在接受新的连接
针对以上功能我们分解一下要实现的模块:
1.多线程实现多个连接,当serverSocket accept到一个连接请求时,开启一个独立的线程
2.实现这个,要求上面新建线程能被网络服务器锁管理
3.服务器不接受其他连接,可以用线程中断做,私有连接能继续,这要求服务器接受连接的服务类必须和私有连接的处理隔离开来
下面不是最后的成品,但我认为尝试过程也会带给人很多启示,所以请跟我一起进行尝试吧。
我们首先想到的方式应该是这样的:
TCPServer类:
1 public class TCPServer extends Thread { 2 3 ServerSocket server = null; 4 volatile boolean shouldstop = false; 5 6 public synchronized void startServer(int port) throws Exception { 7 server = new ServerSocket(port); 8 new TCPServer().start(); 9 } 10 11 public void run() { 12 while (!shouldstop) { 13 try { 14 Socket dataSocket = server.accept(); 15 TCPConnection newConnection = new TCPConnection(dataSocket); 16 newConnection.start(); 17 } catch (IOException e) { 18 e.printStackTrace(); 19 } 20 } 21 } 22 23 public synchronized void stopServer(){ 24 if(server!=null){ 25 shouldstop = true; 26 interrupt(); 27 try { 28 server.close(); 29 } catch (Exception e) { 30 } 31 server = null; 32 } 33 } 34 }
TCPConnection类:
1 import java.net.Socket; 2 3 4 public class TCPConnection extends Thread{ 5 6 public TCPConnection(Socket dataSocket) { 7 8 } 9 10 public void run(){ 11 // dosomething(); 12 } 13 }
TCPServer类在run方法中循环等待接受请求连接,当有请求连接到来时,就为这个私有连接新建一个TCPConnection线程,并启动它。
看上去上面的实现还是可以的,每个连接都能独立运行,而且stopServer方法也做到了关闭server后并影响私有连接的通讯。但是要求二“仅通过继承或实现 TCPServer就能做到对连接功能的修改”
为了完成以上要求,显然要把TCPConnection集成到TCPServer中去。那么如何集成才能做到通过继承或实现 TCPServer 就能做到对连接的修改呢。
这里我采用的方式是让私有连接和TCPServer共享run方法,然后利用标志位来实现私有连接处理自己的事情,服务器Socket循环等待连接。
1 package com.choi.net.server; 2 3 import java.io.IOException; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 7 /** 8 * @author Choi 9 * 10 * @version 1.0 11 * 12 * */ 13 14 public class TCPServer implements Cloneable, Runnable { 15 16 Thread runner = null; 17 protected ServerSocket server = null; 18 Socket data = null; 19 volatile boolean shouldStop = false; 20 21 public synchronized void startServer(int port) throws IOException { 22 if (runner == null) { 23 server = new ServerSocket(port); 24 runner = new Thread(this); 25 runner.start(); 26 } 27 } 28 29 public synchronized void stopServer() { 30 if (server != null) { 31 shouldStop = true; 32 runner.interrupt(); 33 runner = null; 34 try { 35 server.close(); 36 } catch (Exception e) { 37 } 38 server = null; 39 } 40 } 41 42 @Override 43 public void run() { 44 if (server != null) { 45 while (!shouldStop) { 46 try { 47 Socket dataSocket = server.accept(); 48 System.out.println("建立一个连接"); 49 TCPServer newServer = (TCPServer) clone(); 50 newServer.server = null; 51 newServer.data = dataSocket; 52 newServer.runner = new Thread(newServer); 53 newServer.runner.start(); 54 } catch (Exception e) { 55 } 56 } 57 } else { 58 System.out.println("新连接可用"); 59 run(data); 60 } 61 } 62 63 public void run(Socket dataSocket) { 64 System.out.println("空处理"); 65 } 66 }
通过让TCPServer实现cloneable接口的方式来建立新的连接,这样做只是为了方便;当我们为私有连接创建完新线程后把新对象的server赋值为null,这样run方法中的if(server!=null)就能把服务器Socket和私有连接Socket的处理分开了。私有连接的处理是63~65的空方法。
如果想要实现特有功能,只需要继承TCPServer并在子类中从写run(Socket dataSocket)就可以了。
完整的代码和实例,可在我的github主页下载:https://github.com/choitony/TCPServer
标签:
原文地址:http://www.cnblogs.com/chaiwentao/p/4678277.html