• [Java] 网络编程


    网络连接

    • 目的:实现不同主机间数据的共享,早期是主动共享,现在是被动共享
    • OSI七层模型,TCP五层模型,所有数据在每一层上进行信息处理,最终通过物理设备(网卡)发送,网卡在整个网络中有唯一的Mac地址
    • 网络编程:正对于TCP/UDP两种协议进行的网络开发,两个协议的细节组成非常繁琐,对网络协议的抽象性管理逻辑称为Socket编程
    • Socket内部两种模式
      • C/S(Client/Server):需要开发两套程序,一套服务器程序,一套客户端程序,在进行维护的时候服务器端和客户端的程序都需要更新(如QQ),使用特定的数据传输协议(用户自定义)及一些非公开端口,安全性较高
      • B/S(Browser/Server):基于浏览器实现客户端应用,只需要开发服务器端的程序,如需进行维护只需修改服务器代码,维护与开发成本降低,使用公共的HTTP协议(基于TCP协议的实现),所以安全性较差
    • 网络编程属于C/S模型,Web开发属于B/S模型
    • C/S模型分为
      • TCP程序:三次握手,四次挥手
      • UDP程序:发送数据报,接收数据报的一方不一定可以接收到数据(发短信,手机关机)

     

     

    网络程序

    •  java.net包完成,提供两个类
      • java.net.ServerSocket:工作在服务器端的程序类,定义服务器监听端口,及接收客户端请求
      • java.net.Socket:每一个客户端都使用一个Socket的概念进行描述
    • 端口是进入服务的“门”,每个端口只能绑定一个服务,建议用5000以上
    • 连接的目的是进行IO通讯

    服务器端程序

    • 验证服务器是否可正常使用,可利用操作系统中的telnet命令
    • 传输字节数据,用PrintStream
    • win+R > Telnet > open localhost 9999
    • telnet 仅是基础测试环境,不是客户端
    • 服务器端数据的输出,就是客户端数据的输入
    • accept():打开服务器监听
     1 import java.io.PrintStream;
     2 import java.net.ServerSocket;
     3 import java.net.Socket;
     4 
     5 public class HelloServer {
     6     public static void main(String[] args) throws Exception{
     7         ServerSocket serversocket = new ServerSocket(9999); // 本程序在9999端口连接
     8         System.out.println("[HelloServer] 服务器端启动监听... ...");
     9         // 每一个连接到服务器端的客户端都通过Socket对象来描述,所以要等待连接
    10         Socket client = serversocket.accept(); // 等待客户端连接
    11         // 向指定的Socket实现数据的输出,获取Socket的输出流
    12         PrintStream out = new PrintStream(client.getOutputStream()); // 通过打印流输出
    13         out.println("www.yootk.com"); // 输出信息
    14         client.shutdownOutput(); // 数据发送完毕后再关闭
    15         serversocket.close(); // 关闭整个服务器
    16     }
    17 }
    View Code

    客户端程序

    • Socket类描述的就属于客户端信息,在客户端主要用它来实现服务器端的连接,而服务器端每个连接到服务器的客户都通过Socket来描述
     1 import java.net.Socket;
     2 import java.util.Scanner;
     3 
     4 public class HelloClient {
     5     public static void main(String[] args) throws Exception{
     6         // Socket是工作在客户端的程序类,每一个Socket对象描述的都是一个独立的客户端
     7         Socket client = new Socket("localhost",9999);
     8         Scanner scanner = new Scanner(client.getInputStream()); // 服务器端的输出为客户端的输入
     9         if(scanner.hasNext()) { // 此时有数据需要进行输出
    10             System.out.println("[HelloClient] "+scanner.next());
    11         }
    12         client.shutdownInput();
    13     }
    14 }
    View Code

    Echo模型

    • 网络通讯程序的核心接口
    • 客户端发送数据给服务器端,服务器端接收到数据后直接进行回应
    • 回应处理可持续进行,当客户端确认不再继续交互时断开
    • Socket可获取InputStream、OutputStream
    • 实现最为核心的网络接口交互模型,再继续扩展可实现更加丰富内容的传输

    服务器端程序

     1 import java.io.PrintStream;
     2 import java.net.ServerSocket;
     3 import java.net.Socket;
     4 import java.util.Scanner;
     5 
     6 public class EchoServer {
     7     public static void main(String[] args) throws Exception{
     8         ServerSocket serversocket = new ServerSocket(9999);
     9         Socket client = serversocket.accept(); // 进入阻塞状态,等待客户端连接
    10         Scanner scanner = new Scanner(client.getInputStream()); // 服务器端输入流
    11         PrintStream out = new PrintStream(client.getOutputStream()); // 服务器端输出流
    12         boolean flag = true; 
    13         while(flag) {
    14             if(scanner.hasNext()) { // 如果现在有输入的数据内容
    15                 String value = scanner.next().trim();
    16                 if(value.equalsIgnoreCase("exit")) {
    17                     out.println("[EchoServer]exit");
    18                     flag = false;
    19                     break;
    20                 }
    21                 out.println("ECHO:"+ value);
    22             }
    23         }
    24         serversocket.close();
    25     }
    26 }
    View Code

    客户端程序

     1 import java.io.PrintStream;
     2 import java.net.Socket;
     3 import java.util.Scanner;
     4 
     5 public class EchoClient {
     6     public static void main(String[] args) throws Exception{
     7         Socket client = new Socket("localhost",9999);
     8         Scanner scanner = new Scanner(client.getInputStream()); // 客户端输入流
     9         PrintStream out = new PrintStream(client.getOutputStream()); // 客户端输出流
    10         boolean flag = true;
    11         while(flag) {
    12             String value = KeyboardInput.getString("请输入数据:");
    13             out.println(value);
    14             if(scanner.hasNext()) {
    15                 System.out.println("[ECHO客户端]" + scanner.next()); //服务器端响应
    16             }
    17             if(value.equalsIgnoreCase("exit")){
    18                 flag = false;
    19             }
    20         }
    21         client.close();
    22     }
    23 }
    View Code

    BIO处理模型

    • BIO(Blocking IO、阻塞IO处理)是最为传统的一种网络通讯模型的统一描述,解决服务器的并发处理问题,ECHO模型属于单线程服务器的开发,即同一个时间段只能有一个线程进行访问
    • 创建新的线程处理类,包裹Socket对象
    • 问题:需要先连接,然后服务器分配线程对象,若此时客户端即使没有与服务器端产生任何交互,那么这个线程的连接也要维持着,面对高并发访问程序会导致性能浪费,为解决次问题创建了NIO模型

     

    服务器端

     1 import java.net.ServerSocket;
     2 import java.net.Socket;
     3 
     4 public class EchoServer {
     5     public static void main(String[] args) throws Exception{
     6         ServerSocket serversocket = new ServerSocket(9999);
     7         boolean flag = true; 
     8         while(flag) {
     9             Socket client = serversocket.accept();
    10             new Thread(new EchoHandle(client)).start();
    11         }
    12         serversocket.close();
    13     }
    14 }
    View Code

    服务器端线程类

     1 import java.io.PrintStream;
     2 import java.net.Socket;
     3 import java.util.Scanner;
     4 
     5 public class EchoHandle implements Runnable{
     6     private Socket client;
     7     public EchoHandle(Socket client) {
     8         this.client = client;
     9     }
    10     @Override
    11     public void run() {
    12         try {        
    13             Scanner scanner = new Scanner(client.getInputStream()); // 服务器端输入流
    14             PrintStream out = new PrintStream(client.getOutputStream()); // 服务器端输出流
    15             boolean flag = true; 
    16             while(flag) {
    17                 if(scanner.hasNext()) { // 如果现在有输入的数据内容
    18                     String value = scanner.next().trim();
    19                     if(value.equalsIgnoreCase("exit")) {
    20                         out.println("[EchoServer]exit");
    21                         flag = false;
    22                     }else {
    23                         out.println("ECHO:"+ value);
    24                     }
    25                 }
    26             }
    27             scanner.close();
    28             out.close();
    29             client.close();
    30         }catch(Exception e) {}
    31     }
    32 }
    View Code

    客户端

     1 import java.io.PrintStream;
     2 import java.net.Socket;
     3 import java.util.Scanner;
     4 
     5 public class EchoClient {
     6     public static void main(String[] args) throws Exception{
     7         Socket client = new Socket("localhost",9999);
     8         Scanner scanner = new Scanner(client.getInputStream()); // 客户端输入流
     9         PrintStream out = new PrintStream(client.getOutputStream()); // 客户端输出流
    10         boolean flag = true;
    11         while(flag) {
    12             String value = KeyboardInput.getString("请输入数据:");
    13             out.println(value);
    14             if(scanner.hasNext()) {
    15                 System.out.println("[ECHO客户端]" + scanner.next()); //服务器端响应
    16             }
    17             if(value.equalsIgnoreCase("exit")){
    18                 flag = false;
    19             }
    20         }
    21         scanner.close();
    22         out.close();
    23         client.close();
    24     }
    25 }
    View Code

    UDP程序

    • TCP:可靠连接模式,可保证接收稳定性,但会带来严重的性能损耗
    • UDP:不保证用户一定可以收到,但性能较高
    • 类比:发传单
    • 实例:手机短信(不开机收不到)
    • UDP客户端:等待服务器端进行消息数据的发送,如接收到内容则继续向下执行,进行具体内容输出
    • HTTP协议里可能将TCP协议更换
    • 用Netty开发更加简单

    服务器端

     1 import java.net.DatagramPacket;
     2 import java.net.DatagramSocket;
     3 import java.net.InetAddress;
     4 
     5 public class UDPServer {
     6     public static void main(String[] args) throws Exception{
     7         DatagramSocket server = new DatagramSocket(8000); // 服务器端端口
     8         String message = "www.yootk.com";
     9         DatagramPacket packet = new DatagramPacket(message.getBytes(),0,message.length(),InetAddress.getByName("localhost"),9999);
    10         server.send(packet); // 发送数据报
    11         System.out.println("[UDPServer]finished...");
    12         server.close();
    13     }
    14 }
    View Code

    客户端

     1 import java.net.DatagramPacket;
     2 import java.net.DatagramSocket;
     3 
     4 public class UDPClient {
     5     public static void main(String[] args) throws Exception{
     6         DatagramSocket client = new DatagramSocket(9999);
     7         byte data[] = new byte[1024];
     8         DatagramPacket packet = new DatagramPacket(data, data.length);
     9         System.out.println("[UDPClient]wait...");
    10         client.receive(packet);
    11         System.out.println("[UDPClient]"+ new String(data,0,packet.getLength()));
    12     }
    13 }
    View Code

  • 相关阅读:
    pymysql模块及mysql备份
    html基本标签使用
    索引
    多表查询
    Http协议以及请求响应
    web服务器tomcat以及servlet
    XML笔记
    Javascript(2)——BOM
    静态资源三剑客——JavaScript(1)
    静态资源三剑客——CSS
  • 原文地址:https://www.cnblogs.com/cxc1357/p/12460277.html
Copyright © 2020-2023  润新知