zoukankan      html  css  js  c++  java
  • Java笔记15

    网络编程基础

    • 计算机网络: 两台或者更多台计算机组成的网络, 在同一个网络中, 任意两台中计算机可以直接通信, 所有计算机都需要遵守同一种网络协议.
    • 计算机接入互联网, 必须使用TCP/IP协议
    • TCP/IP协议泛指互联网协议, 最重要的两个协议: TCP协议和IP协议

    IP地址

    • IP地址用于唯一标识一个网络接口
    • IPV4: 采用32位地址; IPV6: 采用128位地址
    • 127.0.0.1: 指向本机
    • 公网IP地址和内网IP地址. 公网ip可以直接访问, 内网ip只能内部网络访问(10.*.*.*)``192.168.*.*
    • 如果有一个网卡, 并接入了网络, 就有了一个本机地址, 和ip地址, 可以使用这个ip地址接入网络
    • 如果有两个网卡就可以分别接入不同的网络, 例如路由器和交换机
    • 如果两台计算机位于同一个网络, 那么他们可以直接通信, 因为ip地址的前段是相同的, 也就是网络号是相同的.
    • 网络号: ip地址通过子网掩码过滤后得到的.
    IP = 101.202.99.2
    Mask = 255.255.255.0
    Network = IP & Mask = 101.202.99.0
    
    • 网络号相同, 证明在同一个网路, 可以直接通信
    • 网络号不同, 需要路由器/交换机进行通讯. 也就是网关
    • 网关的作用是链接多个网络
    • 路由: 负责把一个网络的数据包发送到另一个网络

    域名

    • 域名解析服务器DNS负责把域名翻译成对应的IP, 客户端再根据IP访问
    • nslookup [url]
    • nsloopkup www.baidu.com
    Server:  192.168.16.1
    Address: 192.168.16.1#53
    
    Non-authoritative answer:
    www.baidu.com canonical name = www.a.shifen.com.
    Name: www.a.shifen.com
    Address: 61.135.169.121
    Name: www.a.shifen.com
    Address: 61.135.169.125
    

    网络模型

    • OSI网络模型为了简化网络各层操作, 提供标准接口便于实现和维护
    • 模型从上到下:
      • 应用层: 提供应用程序之间的通讯
      • 表示层: 处理数据格式, 加解密等
      • 会话层: 负责建立和维护会话
      • 传输层: 提供端到端的可靠传输
      • 网络层: 负责根据目标地址选择路由来传输数据
      • 链路层和物理层: 负责把数据进行分片并真正通过物理网络传输
    • TCP协议:
      • 应用层; 传输层; IP层; 网络接口层;

    常用协议

    • IP协议: 一个分组协议, 不保证可靠传输

    • TCP协议: 建立在IP协议之上, 传输控制协议, 面向链接的协议, 支持可靠传输和双向通信

    • ip协议只负责发送数据包, 不保证顺序和正确性;

    • tcp协议负责控制数据包传输, 在传输数据之前要先建立连接, 建立链接后才能传输数据, 传输完成后, 断开链接

    • tcp通过接受确认, 超时重传等机制保证数据的可靠传输

    • tcp允许双向通信, 即通信的双方可以同时发送和接受数据

    • tcp协议是应用最广的协议, http和smtp都是建立在tcp协议之上

    • udp协议是一种数据报文协议, 无连接协议, 不保证可靠传输. 在通讯前不需要建立连接, 因此传输效率比tcp高, 并比tcp协议简单; 传输的数据, 需要能够忍受丢失.

    TCP编程

    • 一个应用程序通过一个Socket建立一个远程连接, Socket内部通过TCP/IP协议把数据传输到网络
    • Socket, TCP, 和部分IP的功能由操作系统提供, 不同的编程语言只是提供了对操作系统的简单封装.
    • 操作系统抽出Socket接口, 每个应用程序对应不同的Socket, 数据包才能正确地发到对应的应用程序
    • socket: ip + 端口号. 小于1024的属于特权端口
    • 使用Socket进行网络编程的本质, 是两个进程之间的网络通信.
      • 一个进程充当服务器, 主动监听某个指定的端口
      • 一个进程充当客户端, 主动链接服务器的ip地址和指定端口
      • 连接成功后, 服务器和客户端成功建立一个TCP连接, 双方后续就可以随时发送和接受数据
    • Socket成功建立后:
      • 服务端socket是指定的ipd地址和指定的端口号
      • 客户端的socket是它所在的计算机的ip地址和一个由操作系统分配的随机端口号.

    案例运行顺序

    1. 启动服务器, 监听端口, 一直查看有没有其他socket访问这个端口的.
    2. 有, 便开启一个新的线程 | 客户端链接这个socket
    3. 获取socket的输入和输出 | 客户端获取socket的输入和输出
    4. 服务器端向socket写入'hello'
    5. 客户端读取socket中数据 [server]: hello
    6. 客户端获取屏幕输入的数据, 并写入socket中
    7. 服务器端接受到socket中数据, 修改后, 再次写入socket中
    8. 客户端收到socket中数据, 并打印在屏幕上: ok: ...

    UDP编程

    • udp编程没有创建连接, 数据包一次收发一个, 没有流的概念
    • udp编程使用socket, 指定ip和端口号. 但是和tcp是两套完全独立的端口.

    HTTP编程

    • 超文本传输协议, 基于HTTP协议之上的一种请求-响应协议.

    • 客户端和服务器端首先建立TCP链接, 服务器总是使用80和安全的443端口

    • 然后客户端向服务器发送一个HTTP请求, 服务器端接受后, 返回一个HTTP响应, 包含HTML数据

    • 客户端解析HTML后展示给用户.

    • HTTP协议是固定的, 由header和body组成

    • Header:

      • 第一行总是: 请求方法 路径 HTTP版本号
      • 后面总是: Header: value格式
      • Host: 表示请求的域名, 因为一台服务器上可能含有多个网站, 因此有必要依靠Host进行区分
      • User-Agent: 客户端自身标识
      • Accept: 表示客户端可以处理的HTTP响应格式
      • Accept-Language: 表示客户端接受的语言.
    • Get请求, 只有header没有body.

    • POST请求通常要设置Content-Type表示body类型. Content-Length表示内容长度.

    • POST请求中代用body, 用一个空行分割

    • GET请求的参数必须放到url上, 有长度限制

    • 响应的第一行总是: HTTP版本 响应代码 响应说明

      • 1**: 提示行响应, eg: 101: 切换协议, 常见WebSocket协议
      • 2**: 表示成功: 200表示成功, 206表示发送了部分内容
      • 3**: 表示重定向: eg: 301表示永久重定向, 303表示客户端应该按照指定路径重新发送请求
      • 4**: 表示因为客户端问题导致的错误
      • 5**: 表示服务器端错误
    • 请求图片的时候, 图片会把二进制内容发送给客户端

    • 服务器总是被动的接受客户端的请求, 并并响应他

    • http1.1允许在一个tcp请求中反复发送-响应

    • http2.0允许同时发送多个请求, 返回的时候, 不一定按照顺序返回

    java的Http编程

    • 只讨论客户端的http编程
    • 早期JDK使用HttpURLConnection进行实现
    URL url = new URL("http://www.baidu.com");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setUseCaches(false);
        conn.setConnectTimeout(5000);
        // 设置http请求头
        conn.setRequestProperty("Accept", "*/*");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 11; Windows NT 5.1)");
        // 发送http请求
        conn.connect();
    //    if (conn.getResponseCode() != 200) {
    //      throw new RuntimeException();
    //    }
        // 获取所有的响应
        Map<String, List<String>> map = conn.getHeaderFields();
        for (String key: map.keySet()) {
          System.out.println(key+": "+map.get(key));
        }
        // 获取响应内容
        InputStream input = conn.getInputStream();
    
    public class Client {
      static HttpClient httpClient = HttpClient.newBuilder().build(); // 创建全局实例, 内部使用线程池优化多个http连接
      public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {
        String url = "https://www.sina.com.cn";
        HttpRequest request = HttpRequest.newBuilder(new URI(url))
            .header("User-Agent",  "Java HttpClient")
            .header("Accept", "*/*")
            .timeout(Duration.ofSeconds(5))
            .version(Version.HTTP_2)
            .build();
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        // Http允许重复的header, 因此一个header可对应多个value
        Map<String, List<String>> headers = response.headers().map();
        for(String header: headers.keySet()) {
          System.out.println(header + ": " + headers.get(header).get(0));
        }
        System.out.println(response.body().substring(0, 1024) + "...");
      }
    }
    
    • 获取图片, 使用HttpResponse.BodyHandlers.ofByteArray()进行转换
    • 响应内容很大的时候, 可以使用HttpResponse.BodyHandlers.ofInputStream()获取一个数据流进行加载
    • 使用POST请求, 正确设置Content-type即可

    发送邮件

    • 各个过程:
      • MUA: Mail User Agent
      • MTA: Mail Transfer Agent
      • MDA: Mail Delivery Agent
    • mua给mta发送邮件的协议是SMTP协议 simple mail transfer protocal协议, 使用25端口, 或者加密端口465或587
    • stmp建议在tcp协议之上
    • 一个Multipart可以添加若开个bodypart, 第一个是正文, 后面是附件

    接受邮件

    • 接受邮件使用POP3/IMAP协议

    RMI远程调用

    • 一个jvm可以通过网络实现远程调用另一个jvm的方法
    • remote method invocation
    • 实现RMI服务端和客户端共享一个接口
    • 此接口必定派生自java.rmi.Remote, 并在每个方法中声明RemoteException
    public class Server {
      public static void main(String[] args) throws RemoteException {
        System.out.println("create World clock remote service...");
        // 实例化一个WorldClock:
        WorldClock worldClock = new WorldClockService();
        // 将此服务转换为远程服务接口:
        WorldClock skeleton = (WorldClock) UnicastRemoteObject.exportObject(worldClock, 0);
        // 将RMI端口注册到1099端口
        Registry registry = LocateRegistry.createRegistry(1099);
        // 注册此服务, 服务为"WorldClock"
        registry.rebind("WorldClock", skeleton);
      }
    }
    
    // 客户端调用方法, 通过这个实现类返回结果
    public class WorldClockService implements WorldClock {
      @Override
      public LocalDateTime getLocalDateTime(String zoneId) throws RemoteException{
        return LocalDateTime.now(ZoneId.of(zoneId)).withNano(0);
      }
    }
    
    public interface WorldClock extends Remote {
      LocalDateTime getLocalDateTime(String zoneId) throws RemoteException;
    }
    
    // 客户端只有接口, 并没有实现类, 使用的是服务端实现类获得数据
    public class Client {
      public static void main(String[] args) throws RemoteException, NotBoundException {
        // 连接到服务器, 端口1099
        Registry registry = LocateRegistry.getRegistry("localhost", 1099);
        // 查找服务, 并进行强制转换
        WorldClock worldClock = (WorldClock) registry.lookup("WorldClock");
        // 正常调用接口方法
        LocalDateTime now = worldClock.getLocalDateTime("Asia/Shanghai");
        System.out.println(now);
      }
    }
    
    • 客户端对应的WorldClock对应了一个实现类, 由Registry动态生成, 并把方法调用通过网络传递到服务端.
    • 服务器接受到的网络调用的服务并不是我们自己编写的WorldClockService, 而是Registry自动生成的代码, 我们把客户端的实现类称为stub, 而服务端的网络服务类称为skeleton, 会真正调用worldClockService, 获得结果.
    • rmi严重依赖序列化和反序列化, 这种情况下会造成漏洞, 因此必须是双方信任的内网机器
  • 相关阅读:
    Composite in Javascript
    Model Validation in Asp.net MVC
    HttpRuntime.Cache vs. HttpContext.Current.Cache
    Controller Extensibility in ASP.NET MVC
    The Decorator Pattern in Javascript
    The Flyweight Pattern in Javascript
    Model Binding in ASP.NET MVC
    Asp.net MVC
    jQuery Ajax 实例 全解析
    ASP.NET AJAX入门系列
  • 原文地址:https://www.cnblogs.com/zhangrunhao/p/13173559.html
Copyright © 2011-2022 走看看