一万字❤ 计算机网络知识✔ 带你全面了解网络原理【详解 + 代码演示 + 图解】(期末考试、面试必备)

1. 网络基础

1.1 局域网

通过路由器,将多个电脑连接到一起,构成了局域网(交换机,是对路由器的端口进行扩展的)

1.2 广域网

将多个局域网连接到一起,构成了更加庞大的网络,覆盖范围也更大

局域网和广域网是相对而言的,没有明确的界限

1.3 IP 地址

描述一台设备在网络上的位置。使用一个四字节的数字来表示,点分十进制

1.4 端口号

区分一个主机上不同的应用程序(2个字节)。一个端口号只能被一个程序绑定,但一个程序可以绑定多个端口

范围:0 - 65535

  • 0 一般不使用
  • 1-1023 范围的端口号系统留作特殊用途,其他程序不能占用(22:ssh;23:telnet;80:http;443:https)

网络上本质是通过 光 / 电 信号来传输数据的

1.5 协议

通信双方按照什么样的规则来进行通信

五元组:源 IP,源端口,目的 IP,目的端口,协议类型

1.6 协议分层

网络通信场景比较复杂,很多问题都需要通过协议来解决,如果只有一个大的协议来解决所有问题,这个协议就会非常复杂,不利于学习、理解、维护。将大的协议拆分成多个小的协议,每个协议负责一小块,这样做的话,由于网络协议太复杂,拆分出来的小的协议太多,也不好管理和维护,此时就需要对协议进行分层。

按照协议的 定位/作用 分类,并约定不同层次之间的调用关系,“上层协议调用下层协议,下层协议给上层协议提供服务”,此时即使协议比较多,也可以顺利完成任务

优势

  1. 协议分层之后,上下层彼此之间就进行了封装(使用上层协议,不必过多关注下层,使用下层,也不必过多关注上层)
  2. 每层协议都可以根据需要灵活替换

1.7 网络模型

1.7.1 OSI 七层模型

从下到上分别为 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

分层名称 功能
应用层 针对特定应用的协议
表示层 设备固有数据格式和网络标准数据格式的转换
会话层 通信管理。负责建立和断开通信连接(数据流动的逻辑通路)。管理传输层以下的分层
传输层 管理两个节点之间的数据传输。负责可靠传输(确保数据被可靠地传送到目标地址)
网络层 地址管理与路由选择
数据链路层 互连设备之间传送和识别数据帧
物理层 以 “0”、“1”代表电压的高低、灯光的闪灭。界定连接器和网线的规格。
1.7.2 TCP/IP 五层模型
分层名称 功能 实现
应用层 应用程序如何使用这个数据 应用程序
传输层 关注起点和终点 操作系统的内核
网络层 进行路径规划 操作系统的内核
数据链路层 两个相邻节点之间的数据传输 驱动程序 + 硬件
物理层 描述网络通信的硬件设备(网线、光纤的规格等)。将数据转为 “0”、“1” 信号,通过 光信号/电信号进行传输。对于接收到的数据,将光信号/电信号转换成二进制数据得到以太网数据报交给数据链路层 驱动程序 + 硬件

对于一台主机,操作系统内核实现了从传输层到物理层的内容,即 TCP/IP 五层模型的下四层

对于一台路由器,实现了从网络层到物理层,即 TCP/IP 五层模型的下三层

对于一台交换机,实现了从数据链路层到物理层,即 TCP/IP 五层模型的下两层

对于集线器,只实现了物理层

2. 网络编程

网络编程,需要使用操作系统提供的一组 API 来完成编程。可以认为是应用层和传输层之间交互的方式,成为 Socket API,可以完成不同主机、不同系统之间的网络通信。

传输层的协议主要是 TCP 和 UDP,这两个协议的特性差别很大,操作系统针对这两个协议分别提供了两组 API

2.1 TCP 和 UDP 的区别

  1. TCP 是有连接的,UDP 是无连接的

    有连接:建立连接的双方,各自保存了对方的信息

    • TCP 要通信的话,就得先和对方建立连接,然后才能进行通信

    • UDP 要通信,无需建立连接,直接发送数据即可。不需要征得对方的同意,也不会保存对方的信息。应用层调用 UDP 的 API 的时候,将对方信息传过去就行。

  2. TCP 是可靠传输,UDP 是不可靠传输

    可靠传输:发送方发送数据,是否到达接收方,发送方能够感知到,因此发送方可以在发送失败时采取相应的措施(如重传)

    TCP 内置了可靠传输机制,UDP 没有内置可靠传输机制

    虽然 TCP 是可靠传输,但是并非就更好,因为可靠传输的代价就是机制会更复杂、传输效率会降低

  3. TCP 是面向字节流的,UDP 是面向数据报的

    数据报(Datagram)

    数据包(Packet)

    数据帧(Frame)

    数据段(Segment)

  4. TCP 和 UDP 都是全双工通信

    全双工:可以同时进行双向通信

    半双工:可以进行双向通信,但同一时间只有一个方向可以进行通信

    一根网线中有 8 根线,4个一组,每组都可以独自完成通信,2 组可以实现,当某一根线坏掉时,剩下的也能继续工作。

2.2 UDP的 Socket API

2.2.1 DatagramSocket

Socket 本质上是一个特殊的文件,将网卡这个设备抽象成了文件,往 Socket 中写数据就相当于是发送数据,往 Socket 中读数据,就相当于接收数据。在 Java 中使用 DatagramSocket 来表示系统内部的 Socket 文件

2.2.1.1 构造方法
方法签名 解释
DatagramSocket() 创建一个 UDP 数据报套接字,绑定到本机任意一个随机端口
DatagramSocket(int port) 创建一个 UDP 数据报套接字,绑定到本机指定的端口
2.2.1.2 主要方法
方法签名 解释
void receive(DatagramPacket p) 从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)。参数 p 是一个输出型参数,该方法会将接收到的数据填充到 p 中
void send(Datagram Packet p) 从此套接字发送数据报(不会阻塞等待,直接发送)
void close() 关闭此数据包套接字

客户端和服务器通信,两者都需要创建 Socket 对象,但服务器的 Socket 需要显式指定端口号,客户端的 Socket 一般不显式指定,由客户端操作系统自动分配

服务器端手动指定端口号,是因为开发者清楚该服务器上有什么程序,可以使用哪些端口号,是可控的

而客户端程序在用户电脑上,如果手动指定端口号,有可能这个端口号已经被用户端电脑上的其他程序占用了,就会重现端口冲突,而系统自动分配的话,分配到的肯定是空闲端口

2.2.2 DatagramPacket

用来作为接收和发送的数据报

2.2.2.1 构造方法
签名 解释
DatagramPacket(byte[] buf, int length) 构造一个DatagramPacket来接收数据报,接收到的数据存储于字节数组 buf 中,length 表示接收指定长度的数据(最多接收的数据的字节个数)
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 构造一个DatagramPacket来发送数据报,发送的数据为字节数组 buf 中,从 0 到指定长度length。address 用于指定目的主机 IP 和 端口号
2.2.2.2 主要方法
签名 解释
SocketAddress getSocketAddress() 从数据报中获取发送端主机 IP 地址或接收端主机 IP 地址
int getPort() 获取发送端主机或接收端主机端口号
byte[] getData() 获取数据报中的数据
2.2.3 回显服务器

服务器端

package udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
   
   
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
   
   
        this.socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
   
   
        System.out.println("服务器启动!!!");

        while (true) {
   
   
            // 1. 读取请求并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(requestPacket);

            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());

            // 2. 根据请求计算响应 (实际的业务逻辑)
            String response = process(request);

            // 3. 将响应写回客户端
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length, requestPacket.getSocketAddress());
            socket.send(responsePacket);

            // 4. 打印日志
            System.out.printf("[%s:%d] req=%s, resp=%s", requestPacket.getAddress().toString(), requestPacket.getPort(), request, response);
        }
    }

    public String process(String request) {
   
   
        return request;
    }

    public static void main(String[] args) throws IOException {
   
   
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090);
        udpEchoServer.start();
    }
}

为什么这里不需要调用 close() 关闭文件

  • 这个 socket 是整个进程运行过程中一直都需要用到的
  • 当 socket 不需要使用的时候,意味着进程就结束了,进程的结束,PCB 也被销毁了,文件描述符表也被销毁了,因此不存在文件资源泄露

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Undefined name!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值