zoukankan      html  css  js  c++  java
  • 一个简单网络服务器类的实现

    网络服务器,顾名思义是一个可以接受连接的host,我们要实现的网络服务器类是一个

    1.能够实现多个连接

    2.仅仅通过继承或实现网络服务器类(或接口)的处理就能实现不同的连接功能

    3.当服务器关闭时,已有建立的私有连接不被中断,但服务器不在接受新的连接

    针对以上功能我们分解一下要实现的模块:

    1.多线程实现多个连接,当serverSocket accept到一个连接请求时,开启一个独立的线程

    2.关闭server后不接受连接,为关闭serverSocket的accept所阻塞的线程,关闭有两种方式,一种是中断,一种是close serverSocket。

    下面不是最后的成品,但我认为尝试过程也会带给人很多启示,所以请跟我一起进行尝试吧。

    我们首先想到的方式应该是这样的:

    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 
        
        Socket dataSocket;
    6 public TCPConnection(Socket dataSocket) { 7 this.dataSocket = dataScoket; 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

  • 相关阅读:
    NEC 框架规范 css reset
    NEC 工程师规范
    NEC html规范
    【bzoj2839】【集合计数】容斥原理+线性求阶乘逆元小技巧
    【bzoj1562】【[NOI2009]变换序列】匈牙利算法的性质利用
    【bzoj4808】【马】二分图最大点独立集+简单感性证明
    【hdu1150】【Machine Schedule】二分图最小点覆盖+简单感性证明
    【bzoj4950】【 [Wf2017]Mission Improbable】贪心+二分图匹配
    【bzoj4443】【[Scoi2015]小凸玩矩阵】二分+二分图最大匹配
    【bzoj1977】【严格次小生成树】倍增维护链上最大次大值
  • 原文地址:https://www.cnblogs.com/chaiwentao/p/4678277.html
Copyright © 2011-2022 走看看