• 网络编程


    ---恢复内容开始---

      网络:将地理上分开的主机连接在一起就形成了网络。但是在java中的网络编程不是已物理主机区分的。而是以不同的JVM进程来区分的

      虽然JVM帮助用户隐藏了一些网络原始信息,但是有一些的操作还是留给了用户来实现了,例如:网络的连接分为两种:TCP(可靠的数据连接),UDP(不可靠的数据连接)。

      从网络编程的本质来讲也分为两种类型:

        C/S结构(客户/服务器):需要开发两套程序,一套是服务器端程序,另外一套是客户端程序。如果要更新,两套都要修改,开发复复杂度高,但是安全,稳定,因为可以自定义协议,自定义传输端口;

        B/S结构(浏览器/服务器):通过浏览器来访问服务器端程序,开发者只需要开发服务器端代码即可,只需要维护一套程序,由于使用的是公共的协议,公开的端口,所以安全性较差。

    开发一个基本的C/S程序

      下面编写一个服务器端代码和一个客户端代码,主要是通过客户端去连接服务器端取得一些信息,服务器端只输出一次“HelloWorld”就表示操作结束。

      如果要开发网络程序,使用java.net程序包即可,这个包里面有两个类:ServerSocket(服务器) Socket(客户端)。

    范例:编写一个服务器端程序

     1 package cn.Tony.netdemo.hello.server;
     2 
     3 import java.io.PrintWriter;
     4 import java.net.ServerSocket;
     5 import java.net.Socket;
     6 
     7 public class HelloServer {
     8     public static void main(String[] args) throws Exception {
     9         //1.创建一个服务器端的对象,所有的服务器一定要有一个监听端口
    10         ServerSocket server=new ServerSocket(9999);//此时的服务在9999端口上等待连接
    11         System.out.println("等客户来连接......");
    12         //2.需要等待客户连接,也就是说此时的程序在此处会进入到一个阻塞状态
    13         Socket client=server.accept();//表示等待连接,连接的是客户
    14         PrintWriter out=new PrintWriter(client.getOutputStream());
    15         out.println("Hello World!");//要有换行
    16         out.close();
    17         server.close();
    18     }
    19 }

    范例:编写客户端

    package cn.Tony.netdemo.hello.client;
    
    import java.net.Socket;
    import java.util.Scanner;
    
    public class HelloClient {
    
        public static void main(String[] args) throws Exception{
            //1.表示连接到指定的服务器端的主机名称和端口。localhost=127.0.0.1
            Socket client=new Socket("localhost",9999);
            //2.等待进行服务器端的输出,服务器端输出对客户端是输入4
            Scanner scan=new Scanner(client.getInputStream());
            scan.useDelimiter("
    ");
            if(scan.hasNext()) {
                System.out.println(scan.next());
            }
            client.close();
        }
    }

      这个时候的服务器只能处理一次请求操作

    ECHO程序

      网络编程有一个最为经典的程序案例:ECHO程序的核心本质在于:将用户接受到的数据前面追加一个“ECHO”的头信息进行返回。这个程序要求用户可以一直进行信息的输入,一直到用户byebye才表示操作结束。

    范例:编写服务器端

     1 package cn.Tony.netdemo.echo;
     2 
     3 import java.io.PrintStream;
     4 import java.net.ServerSocket;
     5 import java.net.Socket;
     6 import java.util.Scanner;
     7 
     8 public class EchoServer {
     9     public static void main(String[] args) throws Exception{
    10         ServerSocket server=new ServerSocket(8888);
    11         Socket client=server.accept();
    12         Scanner scan=new Scanner(client.getInputStream());
    13         scan.useDelimiter("
    ");
    14         PrintStream out=new PrintStream(client.getOutputStream());
    15         boolean flag=true;//作为循环的处理标记
    16         while(flag) {//相当于一直循环
    17             if(scan.hasNext()) {//现在客户端有数据发送
    18                 String str=scan.next().trim();//防止有多与空格出现
    19                 if("byebye".equalsIgnoreCase(str)) {//操作结束
    20                     flag=false;//此时循环退出
    21                     break;
    22                 }
    23                 out.println("ECHO:"+str);//做出回应
    24             }
    25         }
    26         out.close();
    27         scan.close();
    28         server.close();
    29     }
    30 }

      随后编写客户端,客户端肯定需要由用户输入数据,自己来输入数据就需要使用System.in并且结合Scanner进行操作,

    范例:

     1 package cn.Tony.netdemo.echo;
     2 
     3 import java.io.PrintStream;
     4 import java.net.Socket;
     5 import java.util.Scanner;
     6 
     7 
     8 public class EchoClient {
     9     public static void main(String[] args)throws Exception {
    10         Socket client=new Socket("localhost",8888);
    11         Scanner keyScan=new Scanner(System.in); //用户输入
    12         keyScan.useDelimiter("
    ");
    13         Scanner netScan=new Scanner(client.getInputStream());
    14         netScan.useDelimiter("
    ");
    15         PrintStream netOut=new PrintStream(client.getOutputStream());
    16         boolean flag=true;
    17         while(flag) {
    18             System.out.println("请输入要发送的信息:");
    19             if(keyScan.hasNext()) {
    20                 String str=keyScan.next();
    21                 netOut.println(str);//发送给服务器端
    22                 if(netScan.hasNext()) {//服务器端有回应
    23                     System.out.println(netScan.next());
    24                 }
    25                 if("byebye".equals(str)) {
    26                     flag=false;
    27                     break;
    28                 }
    29             }
    30         }
    31         keyScan.close();
    32         netScan.close();
    33         client.close();
    34     }
    35 }

      以上完成一个基础的完成,但是程序有一个问题,本程序为单线程,因为所有的操作都在主方法里面进行的。

     1 package cn.Tony.netdemo.echo;
     2 
     3 import java.io.PrintStream;
     4 import java.net.Socket;
     5 import java.util.Scanner;
     6 
     7 
     8 public class EchoClient {
     9     public static void main(String[] args)throws Exception {
    10         Socket client=new Socket("localhost",8888);
    11         Scanner keyScan=new Scanner(System.in); //用户输入
    12         keyScan.useDelimiter("
    ");
    13         Scanner netScan=new Scanner(client.getInputStream());
    14         netScan.useDelimiter("
    ");
    15         PrintStream netOut=new PrintStream(client.getOutputStream());
    16         boolean flag=true;
    17         while(flag) {
    18             System.out.println("请输入要发送的信息:");
    19             String str=null;
    20             if(keyScan.hasNext()) {
    21                  str=keyScan.next().trim();
    22                 netOut.println(str);//发送给服务器端
    23                 if(netScan.hasNext()) {//服务器端有回应
    24                     System.out.println(netScan.next());
    25                 }
    26             }
    27             if("byebye".equalsIgnoreCase(str)) {
    28                 flag=false;
    29                 break;
    30             }
    31         }
    32         keyScan.close();
    33         netScan.close();
    34         client.close();
    35     }
    36 }

      要想解决当前问题就必须进行多线程处理。把每一个连接都封装在一个线程里面,这样处理起来就可以不受到单线程局限了

     1 package cn.Tony.netdemo.echo;
     2 import java.io.PrintStream;
     3 import java.net.ServerSocket;
     4 import java.net.Socket;
     5 import java.util.Scanner;
     6 public class EchoServer {
     7     private static class MyThread implements Runnable{
     8         private Socket client;
     9         public MyThread(Socket client) {
    10             this.client=client;
    11         }
    12         @Override
    13         public void run() {
    14             try {
    15             Scanner scan=new Scanner(client.getInputStream());
    16             scan.useDelimiter("
    ");
    17             PrintStream out=new PrintStream(client.getOutputStream());
    18             boolean flag=true;//作为循环的处理标记
    19             while(flag) {//相当于一直循环
    20                 if(scan.hasNext()) {//现在客户端有数据发送
    21                     String str=scan.next().trim();//防止有多与空格出现
    22                     if("byebye".equalsIgnoreCase(str)) {//操作结束
    23                         out.println("BYEBYE!!!");//做出回应
    24                         flag=false;//此时循环退出
    25                         break;
    26                     }
    27                     out.println("ECHO:"+str);//做出回应
    28                 }
    29             }
    30             out.close();
    31             scan.close();
    32             }catch(Exception e) {
    33                 e.printStackTrace();
    34             }
    35         }
    36     }
    37     public static void main(String[] args) throws Exception{
    38         ServerSocket server=new ServerSocket(8888);
    39         boolean flag=true;
    40         while(flag) {
    41             Socket client=server.accept();
    42             new Thread(new MyThread(client)).start();
    43         }
    44         server.close();
    45     }
    46 }

      实际上所有的服务器上,每一个用户的连接对服务器都是一个线程,线程通过指的就是对共享资源的控制

      网络编程的时代结束了,现在也不再去搞任何编程,

     

    ---恢复内容结束---

  • 相关阅读:
    虚拟机镜像压缩(qcow2,raw)
    CentOS7--删除virbr0
    django简单实例(1)
    python3.7操作mysql数据库
    KVM虚拟化安装部署
    zabbix监控温度及风扇
    excel以某列为基础进行行排序
    kibana添加首页登陆认证
    openstack常见问题解决方法
    linux的7种运行模式
  • 原文地址:https://www.cnblogs.com/Tony98/p/10555960.html
Copyright © 2020-2023  润新知