【网络编程详解】

🌈个人主页努力学编程'

个人推荐
c语言从初阶到进阶
JavaEE详解
数据结构

学好数据结构,刷题刻不容缓点击一起刷题

🌙心灵鸡汤总有人要赢,为什么不能是我呢

🔥🔥🔥网络编程

对于我们之前的编程,基本上都是基于本地机器的运行代码,但是在实际开发的时候,基本上都会有两大部分组成,特别是一些软件的开发,一般会有客户端和服务器,在编写这部分代码的时候,我们的代码要连接网络才能和其他的机器连接.下面给大家讲解一些关于网络的一些比较重要的知识.

⭐⭐⭐IP地址

对于每个每个电脑来说,我们可以进行联网操作,如果我们想要在整个互联网中快速找到这台机器的位置,就会涉及到一个非常重要的知识-IP,本质上来说IP就是这台电脑在互联网中的位置,我们要想找到一台机器的位置,就必须知道其IP地址.

这里教大家如何查看自己电脑的IP的位置

  • 在设置中搜索网络设置
  • 点击网络连接属性即可(win11)

或者win+R,输入cmd,在cmd中输入命令:ipconfig,也可以得到IP地址.

⭐⭐⭐端口号

我们有了IP地址,得到了每台机器的地址,在每台机器中,都会有接收数据,和发送数据的过程.端口就是记录每个接收数据和发送数据的进程,所以端口号本质: 端⼝号⽤于定位主机中的进程

就比如发送快递的时候,不但要填写收货地址(IP地址),还要填写收件人(端口)

此时虽然我们已经可以定位到一个电脑的IP地址,和端口(机器中的唯一的进程),但是网络通信的时候,我们传输数据的时候,都是将数据转换为0101这样的二进制的数据,然后传给另一台机器,但是接收的一方,如何由一堆的二进制代码,判断此时传输的数据到底是文本文件还是视频,还是图片,所以我们就得约定一套固定的东西来约定一下这些东西-协议

⭐⭐⭐协议

协议的作用就是为了在进行网络通信的时候,使每台电脑能够按照同一套规则进行数据的解析,这样就会让每一台电脑的数据都可以被其他的电脑接受和解析.总而言之,协议就是对于如何进行网络通信做了一个约定

由于网络通信的整个过程的细节非常庞大,如果只使用一个协议,就会导致这个协议结构复杂化,且有了高耦合的问题,所以就会对协议进行分层,每一层只干一个/一类问题,

OSI七层模型:

这种分层模式只存在于教科书中,并没有在实际应用中大量采用,在实际场景中我们最常用的是TCP/IP五层网络模型.

对于这五层模型,我们必须要理解,并最好可以熟练的讲出来,这也是我们面试的时候的一个高频考点.

  1. 应用层: 针对特定应用的协议
  2. 传输层:传输层只关注网络通信的起点和终点,并不关心其中的细节,
  3. 网络层:进行网络通信的路径规划,同时还要负责地址的管理.
  4. 数据链路层:对于上面规划好的路线进行具体的实现,并对路线的具体过程有简单的记录
  5. 物理层:描述的是硬件层面需要满足怎样的条件,例如(网线有8根线)

而对于程序员来说我们可以干预的只有应用层,其他的都是交给操作系统或者硬件设备.

⭐⭐⭐网络设备所在的分层:

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

• 对于⼀台路由器,它实现了从⽹络层到物理层,也即是TCP/IP五层模型的下三层;

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

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

🔥🔥🔥封装

对于网络通信的时候,如何传输数据的,这里一共有两个过程,封装和分用.

举个例子:

你使用QQ发送了一个hello给你的同学,此时你在输入框中输入字符串之后,数据就会被打包为一个应用层数据包,里面可能会有你的QQ号,接受者的QQ号,消息的发送时间,消息的内容...

然后应用层数据包就会以参数的形式被传递给传输层API调用,进入传输层,在传输层中进一步对数据进行包装,称为一个传输层数据包(传输层这里有很多协议,这里使用UDP演示).

进一步传输层数据包也会调用网络层的API,进入网络层,在网络层中也有很多的协议,这里我们以IPv4为例,在日常开发中如果没有强调的话,说的都是IPv4, IPv6还没有大量普及...然后对数据作进一步的加工处理:

然后进一步调用数据链路层的API,进入数据链路层,这里的协议主要是以太网,(我们平时的网线就是这个),对数据作进一步的加工-添加以太网帧头帧尾.

最后数据进入到物理层,将二进制数据转化为光信号,电信号这样的数据传输给真正的物理硬件...

我们上述都是在消息发送者的角度观察的,现在消息发出去,进入接受者视角,这个过程,其实和我们上述的过程刚好是相反的,对数据一步一步进行解析,这道最后进入应用层展示接受到的数据.

🔥🔥🔥网络套接字

操作系统给应用程序提供的API(传输层给应用层提供的API),即socket api

接下来我们就学习的是操作系统给到我们提供的socket(Java版)

这里的socket api提供了两个不同版本的api, UDP, TCP,

这里也有一个经典的面试题:UDP和TCP的区别:

  • TCP:有连接,可靠传输,面向字节流,双全工.
  • UDP:无连接,不可靠传输,面相数据报,双全工.
  1. 有无连接: 此处谈到的连接,并不是物理层面的连接,而是一种"抽象" 的连接.通信对方都保存了对方的信息,这就相当于"有连接",如果没有保存对方的信息,就表示的是"无连接"
  2. 是否可靠传输: 这里的可靠传输,并非是只100%可以到达对方,而是尽可能 相对来说不可靠传输:就是完全没有考虑是否能够达到对方~
    TCP:内置了一些机制,能够保证,可靠传输.
  • 感知到对方是不是收到了
  • 对方没有收到时,进行重试

UDP则没有可靠性机制

UDP则完全不管数据是否顺利传到了对方

面相字节流:

这里的字节流就和文件流/水流是一样的特点.

我们可以一次从文件中读取100个字节,也可以一次读写50个字节...

TCP可以一次读写100个字节,第二次50个字节...

面向数据报:

UDP每次传输数据的时候,都是以数据报为一个单位进行传输的.

双全工:一个通信链表,可以发送数据/也可以接受数据(双向通信)

预支对用的:单双工:一个通信链路,只能发送/只能接受(单向通信)

🔥🔥🔥UDP和TCP的使用

这里主要介绍一下UDP的使用,首先了解UDP的API

DatagramSocket 代表一个socket对象(可以理解为网卡这种硬件设备的抽象表达形式),我们就可以后面利用 DatagramSocket 间接操作网卡.

DatagramPacket代表一个数据报,里面的构造方法,可以出传递数据信息,IP地址以及端口号.

我们想要简单实现一个网络编程的场景,就需要两个程序:

  1. UDP 服务器
  2. UDP 客户端

主动发起通信的一方我们称为客户端,另一方就是服务器.

🔥🔥🔥UDP实现网络编程

这里我们模拟实现一个客户端给服务器发送一条短信 hello 的整个过程

服务器代码:

java 复制代码
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 {
        socket=new DatagramSocket(port);
    }

    //通过 start 启动服务器的核心流程
    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());

            //4.把日志打印一下
            System.out.printf("[%s:%d] req=%s, resq=%s\n",requestPacket.getAddress(),requestPacket.getPort(),
                    request,response);
        }
    }
    public String process(String request){
        return request;
    }

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

客户端代码:

java 复制代码
import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIP;
    private int serverPort;

    public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
        socket = new DatagramSocket();
        this.serverIP = serverIP;
        this.serverPort = serverPort;
    }

    public void start() throws IOException {
        System.out.println("启动客户端");
        Scanner scanner = new Scanner(System.in);

        while (true) {
            // 1. 从控制台读取到用户的输入.
            System.out.print("-> ");
            String request = scanner.next();
            // 2. 构造出一个 UDP 请求, 发送给服务器.
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
                    InetAddress.getByName(this.serverIP), this.serverPort);
            socket.send(requestPacket);
            // 3. 从服务器读取到响应
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            // 4. 把响应打印到控制台上.
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        // UdpEchoClient client = new UdpEchoClient("47.108.28.88", 9090);
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        client.start();
    }
}
相关推荐
ServBay7 小时前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954489 小时前
CTF 伪协议
php
BingoGo3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack3 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack4 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack5 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo5 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack6 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理6 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php