zoukankan      html  css  js  c++  java
  • 用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰

    服务器:

    1.与客户端的交流手段多是I/O流的方式

    2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接

    3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输入流,同时所有客户端的所有输出流都会包含在服务器的输入流中。

    (即套接字即使建立连接,输入输出流都是相对自己的而言的,向外发送自己的内部的信息都用输出流,接受外部的数据都使用输入流!)

    简单服务器的代码实现:

    public static void main(String [] args){
      try {
      //建立本地服务端,并监听6788端口号   ServerSocket server
    = new ServerSocket(6788); //获取键盘输入,作为服务器向客户端发送的信息
        Scanner reader
    = new Scanner(System.in); while (true) {   Socket c = server.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(c.getOutputStream())); String line; if ((line=br.readLine())!=null) {   System.out.println(line); } if ((line=reader.nextLine())!=null) {   bw.write(line); bw.newLine();//由于判断的时候都是nextline(),所以每次输入都必须自己给出一个换行 bw.flush(); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    与服务器链接并实现交流的客户端代码实现:

    public static void main(String[] args) {
            try {
          //连接到本地主机的6788端口(127.0.0.1为本地主机IP) Socket c
    = new Socket("127.0.0.1",6788); //获取键盘输入信息,做为向服务器发送的信息 Scanner reader = new Scanner(System.in); BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(c.getOutputStream())); String line; while(true){ if ((line = reader.nextLine())!=null) { bw.write(line); bw.newLine();  //客户端和服务器的读取操作都是行,所以需要自己给出换行,避免出错 bw.flush(); } if ((line=br.readLine())!=null) { System.out.println(line); } } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    一般服务器绝不可能只为一个客户端服务,当存在很多客户端的时候,需要为每个客户端的链接建立独立的线程,使得客户端之间不会干扰,独立运行。

    线程的控制实现方法有两种:

    1.自定义线程类继承Thread,并重现run()方法;

    2.自定义一个普通类,实现Runnable接口(本文采用此方法实现多线程控制)

    具体代码实现:

    //服务器的代码
    public
    static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(6666); while (true) {
              //一直监控是否有客户端连接 Socket s
    = serverSocket.accept(); //每当有客户端连接时,为每个客户端开辟独立线程执行 Thread ch = new Thread(new ThreadManager(s)); ch.start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    实现线程的自定义类:

    public class ThreadManager implements Runnable{
    
        private Socket socket;
        
        public ThreadManager(Socket s){
            this.socket = s;
        }
        @Override
        public void run() {
            BufferedWriter bw;
            BufferedReader br;
            try {
                bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
               //连续不断地向客户端发送信号,数字不断在变化,若客户端先后链接,发送的信息独立则独立线程实现 
           for(int i = 0; i<1000000;i++){
            bw.write(i+"````````````````");
            bw.newline();
            bw.flush();
            }
    } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

    用来接收服务端的客户端代码实现:

    public static void main(String[] args) {
            try {
            //链接到本地的6666端口 Socket s
    = new Socket("127.0.0.1",6666 ); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line; while(true){ while ((line = br.readLine())!=null) { //将服务器发送的信息输出
              System.out.println(line); }
    } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    注:为方便观察,可在cmd窗口中启动客户端的代码,重复打开几个dos窗口,并链接到本地的6666端口,就会收到服务器发送过来的递增的数字,所有的dos窗口都启动后,可以发现每个窗口的数字增长的程度并不相同,但都一直在运行,互不干扰,至此,为客户端创立的独立线程实现。

    注:还有很多的网络知识未曾收集和整理,当自己再次看到这里的时候,记得补足基础部分,以再次夯实基础,加强回忆。

  • 相关阅读:
    [pixhawk笔记]8-半物理仿真环境
    Python超参数自动搜索模块GridSearchCV上手
    Oriented Response Networks 阅读笔记(一)
    聚类算法评价指标学习笔记
    基于sklearn的常用分类任务指标Python实现
    使用h5py库读写超过内存的大数据
    基于MXNet使用自己的图像数据集训练网络--准备数据与撰写预处理脚本
    在Ubuntu操作系统中添加环境变量
    Jetson TK1 开发板初用体会
    一条脚本搞定OpenCV
  • 原文地址:https://www.cnblogs.com/thinfog/p/5658797.html
Copyright © 2011-2022 走看看