20、网络编程实战

C++20协程实战:从回调地狱到高性能异步网络编程 协程是一种轻量级的用户态线程,通过挂起和恢复机制实现协作式多任务。其核心原理在于将程序执行流本地化管理,在遇到I/O等待时主动让出CPU,事件就绪后从挂起点精确恢复。这种机制为异步编程带来了革命性价值,让开发者能用同步的代码风格编写高性能并发逻辑,极大提升了代码可读性和可维护性。在C++20中,无栈协程通过编译器生成状态机实现,配合`co_await`表达式,成为构建高并发网络服务的利器。特别是在网络编程领域,协程能优雅解决传统回调模式下的逻辑碎片化问题,使得处理海量连接的游戏服务器、金融交易系统等场景的代 阅读详情

一、概述

  • 地球村:你在西安,你一个美国的朋友!
  • 信件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SZWKTtD3-1614584904637)(E:\硕士研究\Java学习历程\20、网络编程实战(信件原理)].png)

  • 计算机网络:

    ​ 计算机网络是指将**地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来**,在网络操作系统,网络管理软件及**网络通信协议**的管理和协调下,实现资源共享和信息传递的计算机系统。

  • 网络编程的目的:

    无线电台 —> 传播交流信息、数据交换、通信

  • 想要达到这个效果需要什么:

    • 如何准确地定位网络上的一台主机 192.168.16.124: 端口,定位到这个计算机上的某个资源
    • 找到了这个主机,如何传输数据呢?
  • 网络编程和网页编程

    • 网络编程 TCP/IP C/S
    • 网页编程 JavaWeb B/S

二、网络通信的要素

  • 如何实现网络的通信?

  • 通信双方的地址:

    IP、端口号

  • 规则:网络通信的协议:http、ftp、smtp、tcp、udp…

    TCP/IP参考模型:

    在这里插入图片描述

三、IP

  • IP地址:InetAddress类

  • 唯一定位一台网络上的计算机

  • 本机 localhost:127.0.0.1

  • IP地址的分类:

    • ipv4 / ipv6

      • ipv4:127.0.0.1,4个字节组成,0~255,42亿:北美30亿,亚洲4亿,2011年已用尽;

      • ipv6:fe80::35bb:3e82:d451:cb96%19,128位,8个无符号整数;

        2001:0bb2:aaaa:0015:0000:0000:1aaa:1312
        
    • 公网(互联网)/ 私网(局域网)

      • ABCD类地址(查资料)

        IP地址分为五类,A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同。

        其中A类、B类、和C类这三类地址用于TCP/IP节点,其它两类D类和E类被用于特殊用途。
        A、B、C三类IP地址的特征:当将IP地址写成二进制形式时,A类地址的第一位总是O,B类地址的前两位总是10,C类地址的前三位总是110。

        1. A类IP地址

        一个A类IP地址由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”, 地址范围从1.0.0.0 到126.0.0.0。可用的A类网络有126个,每个网络能容纳1亿多个主机。

        ⑴ A类地址第1字节为网络地址,其它3个字节为主机地址。
        ⑵ A类地址范围:1.0.0.1—126.155.255.254
        ⑶ A类地址中的私有地址和保留地址:
        ① 10.X.X.X是私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。
        ② 127.X.X.X是保留地址,用做循环测试用的。

        2. B类IP地址

        一个B类IP地址由2个字节的网络地址和2个字节的主机地址组成,网络地址的最高位必须是“10”,地址范围从128.0.0.0到191.255.255.255。可用的B类网络有16382个,每个网络能容纳6万多个主机 。

        ⑴ B类地址第1字节和第2字节为网络地址,其它2个字节为主机地址。
        ⑵ B类地址范围:128.0.0.1—191.255.255.254。
        ⑶ B类地址的私有地址和保留地址
        ① 172.16.0.0—172.31.255.255是私有地址
        ② 169.254.X.X是保留地址。如果你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器。就会得到其中一个IP。

        3. C类IP地址

        一个C类IP地址由3字节的网络地址和1字节的主机地址组成,网络地址的最高位必须是“110”。范围从192.0.0.0到223.255.255.255。C类网络可达209万余个,每个网络能容纳254个主机。

        ⑴ C类地址第1字节、第2字节和第3个字节为网络地址,第4个个字节为主机地址。另外第1个字节的前三位固定为110。
        ⑵ C类地址范围:192.0.0.1—223.255.255.254。
        ⑶ C类地址中的私有地址:
        192.168.X.X是私有地址。

        4. D类地址用于多点广播(Multicast)。

        D类IP地址第一个字节以“1110”开始,它是一个专门保留的地址。它并不指向特定的网络,目前这一类地址被用在多点广播(Multicast)中。多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。

        ⑴ D类地址不分网络地址和主机地址,它的第1个字节的前四位固定为1110。
        ⑵ D类地址范围:224.0.0.1—239.255.255.254

        5. E类IP地址

        以“11110”开始,为将来使用保留。

        全零(“0.0.0.0”)地址对应于当前主机。全“1”的IP地址(“255.255.255.255”)是当前子网的广播地址。

        ⑴ E类地址也不分网络地址和主机地址,它的第1个字节的前五位固定为11110。
        ⑵ E类地址范围:240.0.0.1—255.255.255.254

        6. 在IP地址3种主要类型里,各保留了3个区域作为私有地址,其地址范围如下:

        A类地址:10.0.0.0~10.255.255.255

        B类地址:172.16.0.0~172.31.255.255

        C类地址:192.168.0.0~192.168.255.255

        7. 子网掩码

        **子网掩码(subnet mask)**又叫网络掩码、地址掩码、子网络遮罩,它是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。

        **子网掩码不能单独存在,它必须结合IP地址一起使用。**子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。子网掩码是一个32位地址,用于屏蔽IP地址的一部分以区别网络标识和主机标识,并说明该IP地址是在局域网上,还是在远程网上。

        子网掩码——屏蔽一个IP地址的网络部分的“全1”比特模式。
        对于A类地址来说,默认的子网掩码是255.0.0.0;
        对于B类地址来说默认的子网掩码是255.255.0.0;
        对于C类地址来说默认的子网掩码是255.255.255.0。

      • 192.168.xx.xx:专门给组织内部使用的

  • 域名:记忆IP问题!

    • IP:www.vip.com
package com.cwlin.lesson01;

import java.net.InetAddress;
import java.net.UnknownHostException;

//测试IP
public class TestInetAddress {
    public static void main(String[] args) {
        try {
            //查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress1);
            InetAddress inetAddress3 = InetAddress.getByName("localhost");
            System.out.println(inetAddress3);
            InetAddress inetAddress4 = InetAddress.getLocalHost();
            System.out.println(inetAddress4);

            //查询网站ip地址
            InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress2);

            //常用方法
            //System.out.println(inetAddress2.getAddress()); //地址
            System.out.println(inetAddress2.getCanonicalHostName()); //规范的名字
            System.out.println(inetAddress2.getHostAddress()); //ip
            System.out.println(inetAddress2.getHostName()); //域名,或者自己电脑的名字
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

四、端口

  • 端口表示计算机上的一个程序的进程。

  • 不同的进程有不同的端口号,用来区分软件!

  • 被规定为0~65535

  • TCP/UDP:65535*2,TCP:80和UDP:80不冲突;在单个协议下,端口号不能冲突

  • 端口分类:

    • 公有端口 0~1023
      • HTTP: 80;
      • HTTPS: 443;
      • FTP: 21;
      • Telent: 23
    • 程序注册端口 1024~49151,分配给用户或者程序
      • Tomcat: 8080
      • MySQL: 3306
      • Oracle: 1521
    • 动态、私有:49152~65535
    netstat -ano #查看所有端口
    netstat -ano|findstr "49664" #查看指定端口
    tasklist|findstr "21796" #查看指定端口的进程
    
package com.cwlin.lesson01;

import java.net.InetAddress;
import java.net.InetSocketAddress;

//测试ip+port
public class TestInetSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080);
        InetSocketAddress socketAddress2 = new InetSocketAddress("localhost",8080);
        System.out.println(socketAddress);
        System.out.println(socketAddress2);
        System.out.println(socketAddress.getAddress()); //ip
        System.out.println(socketAddress.getPort()); //端口
        System.out.println(socketAddress.getHostName()); //地址(hosts文件可修改)
    }
}

五、通信协议

  • 协议:约定,

  • 网络通信协议:速率、传输码率、代码结构、传输控制…

  • 问题:非常复杂?

  • 解决:大事化小!分层!

  • TCP/IP协议簇:实际上是一组协议

  • 重要协议:

    • TCP:用户传输协议
    • UDP:用户数据报协议
  • 出名的协议:

    • TCP:传输控制协议
    • IP:网络互联协议

在这里插入图片描述

  • TCP和UDP的对比

    • TCP:打电话

      • 连接,稳定

      • 三次握手、四次挥手

      • 客户端、服务端

      • 传输完成,释放连接,效率低

    • UDP:发短信

      • 不连接,不稳定
      • 客户端、服务端:没有明确的界限
      • 不管有没有准备好,都可以发给你
      • 导弹
      • DDOS:洪水攻击!(饱和攻击)
    • TCP的三次握手、四次挥手

      • 概述:

        最少需要三次,保证连接稳定!
        A: 你愁啥?
        B: 瞅你咋地?
        A: 干一场!
        
        最少需要四次,保证彻底断开!
        A: 我要走了!
        B: 我真的要走了吗?
        B: 你真的真的要走了吗?
        A: 我真的要走了!
        
      • 详解:

      在这里插入图片描述
      在这里插入图片描述

      • 通俗理解:

      在这里插入图片描述
      在这里插入图片描述

六、TCP

6.1、发送消息

  • 客户端
    1. 连接服务Socket
    2. 发送消息
package com.cwlin.lesson02;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

//客户端
public class TcpClientDemo01 {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        try {
            //1.要知道服务器的地址、端口号
            InetAddress serverIp = InetAddress.getByName("127.0.0.1");
            int port = 9999;
            //2.创建一个socket连接
            socket = new Socket(serverIp,port);
            //3.发送消息 IO流
            os = socket.getOutputStream();
            os.write("你好,欢迎学习网络编程".getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 服务器

    1. 建立服务的端口 ServerSocket

    2. 等待用户的连接 accept

    3. 接收用户的消息

package com.cwlin.lesson02;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

//服务端
public class TcpServerDemo01 {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.我得有一个地址
            serverSocket = new ServerSocket(9999); //插槽
            while (true){
                //2.等待客户端连接过来
                socket = serverSocket.accept();
                //3.读取客户端的消息
                is = socket.getInputStream();

                //管道流
                baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len=is.read(buffer))!=-1){
                    baos.write(buffer,0,len);
                }
                System.out.println(baos.toString());
            }


            /* 比较的方法,若中文在中间断掉,会乱码
                byte[] buffer = new byte[1024];
                int len;
                while ((len=is.read(buffer))!=-1){
                    String msg = new String(buffer, 0, len);
                    System.out.println(msg);
                }
             */
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            if (baos != null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket != null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }



        }
    }
}

6.2、文件上传

  • 客户端
package com.cwlin.lesson02;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建一个Socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();
        //3.读取文件
        FileInputStream fis = new FileInputStream(new File("send.png"));
        //4.写入文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len=fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }

        //通知服务器已经传输结束
        socket.shutdownOutput();
        //确定服务器接收完毕,才能断开连接
        InputStream inputStream = socket.getInputStream();
        //String byte[]
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while ((len2=inputStream.read(buffer2)) != -1){
            byteArrayOutputStream.write(buffer2,0,len2);
        }
        System.out.println(byteArrayOutputStream.toString());

        //5.关闭资源
        byteArrayOutputStream.close();
        inputStream.close();
        fis.close();
        os.close();
        socket.close();
    }
}
  • 服务器
package com.cwlin.lesson02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServerDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端的连接
        Socket socket = serverSocket.accept();
        //3.获取输入流
        InputStream is = socket.getInputStream();
        //4.文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.png"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len=is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }

        //通知客户端已经接收完毕
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("已经接收完毕,可以断开".getBytes());

        //5.关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

6.3、Tomcat

  • 服务端

    • 自定义 S
    • Tomcat服务器 S:Java后台开发!
  • 客户端

    • 自定义 C
    • 浏览器 B

七、UDP

7.1、发送消息:不用连接,只需要知道对方的地址!

  • 发送端
package com.cwlin.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//不需要连接服务器
public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        //2.建个包
        String msg = "你好啊,服务器!";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        //数据,数据的起止,要发送给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
        //3.发送包
        socket.send(packet);
        //4.关闭流
        socket.close();
    }
}
  • 接收端
package com.cwlin.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

//还是要等待客户端的连接!
public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception {
        //开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        socket.receive(packet); //阻塞接收
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        //关闭连接
        socket.close();
    }
}

7.2、咨询:循环发送消息和接收消息!

  • 发送端:循环发送消息
package com.cwlin.chat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8888);
        //准备数据:控制台读取System.in
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true){
            String data = reader.readLine();
            byte[] sendData = data.getBytes();
            DatagramPacket packet = new DatagramPacket(sendData,0,sendData.length,new InetSocketAddress("localhost",6666));

            socket.send(packet);
            if (data.equals("bye")){
                break;
            }
        }
        socket.close();
    }
}
  • 接收端:循环接收消息
package com.cwlin.chat;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UdpReceiveDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);
        while (true){
            //准备接收包裹
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container,0,container.length);
            socket.receive(packet); //阻塞式接收包裹
            //断开连接 bye
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, data.length);

            System.out.println(receiveData);
            if (receiveData.equals("bye")){
                break;
            }
        }
    }
}

7.3、在线咨询:两个人都可以是发送方和接收方!

  • 发送线程
package com.cwlin.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class TalkSend implements Runnable {
    DatagramSocket socket = null;
    BufferedReader reader = null;

    private int fromPort;
    private String toIP;
    private int toPort;

    public TalkSend(int fromPort, String toIP, int toPort) {
        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;

        try {
            socket = new DatagramSocket(fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true){
            String data = null;
            try {
                data = reader.readLine();
                byte[] sendData = data.getBytes();
                DatagramPacket packet = new DatagramPacket(sendData,0,sendData.length,new InetSocketAddress(this.toIP,this.toPort));

                socket.send(packet);
                if (data.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        socket.close();
    }
}
  • 接收线程
package com.cwlin.chat;

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

public class TalkReceive implements Runnable {
    DatagramSocket socket = null;
    private int port;
    private String msgFrom;

    public TalkReceive(int port, String msgFrom) {
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true){
            try {
                //准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet); //阻塞式接收包裹
                //断开连接 bye
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, data.length);

                System.out.println(msgFrom + ":" + receiveData);
                if (receiveData.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 老师端
package com.cwlin.chat;

public class TalkTeacher {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(5555,"localhost",8888)).start();
        new Thread(new TalkReceive(9999,"学生")).start();
    }
}
  • 学生端
package com.cwlin.chat;

public class TalkStudent {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkReceive(8888,"老师")).start();
    }
}

八、URL

8.1、概述

  • 统一资源定位符:定位资源、定位互联网上的某一个资源

  • DNS域名解析 www.baidu.com xxx.x.x.x

  • 格式:协议://IP地址:端口/项目名/资源

8.2、URL基本内容

package com.cwlin.lesson05;

import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo01 {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhsot:8080/helloworld/index.jsp?username=cwlin&password=123456");
        System.out.println(url.getProtocol()); //协议:http
        System.out.println(url.getHost()); //主机IP:localhost
        System.out.println(url.getPort()); //端口:8080
        System.out.println(url.getPath()); //文件:/helloworld/index.jsp
        System.out.println(url.getQuery()); //参数:username=cwlin&password=123456
        System.out.println(url.getFile()); //全路径:/helloworld/index.jsp?username=cwlin&password=123456
    }
}

8.3、URL下载网络资源

package com.cwlin.lesson05;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class URLDownload {
    public static void main(String[] args) throws Exception {
        //1.下载地址
        //网页图片: https://p2.music.126.net/4WuOpPZeK7hH8bqn28G-Dg==/109951165315490238.jpg?param=130y130
        //网页音乐: https://ws.stream.qqmusic.qq.com/C4000046fqfQ3mSaUo.m4a?guid=446211115&vkey=C8A1B9D42E3F101F2A7D0F98AEECA5CE2F5AB629A9533212BA47BB36B8680B85796E7C91E2D71DF5295FD18BAE714E50A6F89C5B04E3786B&uin=1208793450&fromtag=66
        URL url = new URL("http://localhost:8080/cwlin/SecurityFile.txt");
        //2.连接到这个资源 HTTP
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream("漫长的告白.m4a");
        byte[] buffer = new byte[1024];
        int len;
        while ((len=inputStream.read(buffer))!=-1){
            fos.write(buffer,0,len); //写出这个数据
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect(); //断开连接
    }
}
C++20协程实战:从原理到高并发网络编程应用 协程作为一种轻量级的并发编程模型,通过允许函数在执行过程中挂起和恢复,实现了高效的异步操作处理。其核心原理在于将执行状态保存在独立的协程帧中,而非依赖传统线程栈,从而大幅降低上下文切换开销。在C++20中,这一技术通过无栈协程实现,提供了零开销抽象,使得开发者能够以同步代码的思维编写异步逻辑,显著提升代码可读性和维护性。从技术价值看,协程尤其适用于I/O密集型和高并发场景,如网络服务器、游戏引擎等需要处理大量并发连接的后端服务。通过`co_await`、`co_yield`等关键字,开发者可以构建高效的异步 阅读详情

相关推荐

Boost.Asio实战指南:从异步回调到C++20协程的网络编程

网络编程的核心在于高效处理异步I/O和并发连接,而C++开发者常面临回调地狱和线程同步的挑战。Boost.Asio作为C++网络编程的事实标准库,提供了强大的异步I/O模型,但其复杂的学习曲线让许多开发者望而却步。通过理解事件驱动架构和Reactor模式,开发者可以掌握非阻塞I/O和事件循环机制,从而构建高性能服务器。在工程实践中,生命周期管理和资源回收是关键,需要确保异步操作期间对象的有效性。随着C++20协程的普及,Boost.Asio的协程支持让异步代码的编写更加直观,大幅降低了心智负担。无论是构建T

weixin_32288959的博客 226

让nmap为你的操作系统护航

nmap最基本最核心的功能是端口扫描,通过端口扫描就可以开始你的神操作。今天我带领你用nmap来为你的操作系统护航吧! 准备条件: 服务方:kali 服务对象:windows10系统 一. kali要能ping通windows10。 二.nmap端口扫描,找到危险端口或可疑端口(可能是木马)。 我用的是全端口扫描,3389端口是危险端口,可关闭此端口。​​​​ ...

m0_58231750的博客 1564

C++20协程实战:构建高性能异步网络编程模型

协程是一种轻量级的用户态线程,它允许函数在执行过程中被挂起和恢复,而无需阻塞操作系统线程。其核心原理在于通过保存和恢复执行上下文,实现协作式多任务调度。这一机制在I/O密集型场景中极具技术价值,能有效避免线程阻塞和上下文切换开销,大幅提升并发性能。在异步网络编程领域,传统基于回调或Future/Promise的模型常导致代码逻辑割裂、状态管理复杂,形成所谓的“回调地狱”。C++20标准引入的无栈协程原生支持,为这一痛点提供了优雅的解决方案。通过将网络I/O操作封装为可等待体(Awaitable),并与事件循

weixin_32050773的博客 212

解决端口占用问题

1:首先,打开cmd窗口,输入以下命令查看指定端口占用情况(以下以8080端口为例) netstat -aon|findstr"8080" 可以看到,端口被11588的进程占用了,接下来查看该PID的进程 协议 本地地址 外部地址 进程状态 PID TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 11588 TCP ...

踏风彡的博客 2551

C++20协程实战:从原理到异步任务框架与网络编程应用

协程作为现代异步编程的核心概念,通过无栈设计实现轻量级并发,其原理基于状态机转换而非传统线程切换。在C++20中,协程通过编译器生成的Promise、Awaitable和协程句柄三驾马车协作,将异步操作转化为看似同步的代码逻辑,极大提升了I/O密集型应用的可维护性。这一技术价值在于解决了回调地狱问题,同时保持了高性能,尤其适用于网络请求、事件驱动框架和生成器场景。本文以构建简易Task框架为例,深入解析了co_await、co_yield等关键字的底层机制,并展示了如何与asio等网络库整合,实现高效的异步

weixin_30702441的博客 320

TCPIP端口号大全

TCPIP端口

系统漏洞复现与勒索病毒

信息安全第二节,渗透测试相关,kali及win系统操作

goldfish8848的博客 2698

网络编程斗地主ppt答辩文档

一个斗地主程序的开发文档,是一个网络版,程序采用C/S模型,要程序的话可以给我留言。

【Windows】之解决端口被占用问题

1、启动 windows 的命令窗口,按键盘上的 win + R, 然后在输入框中输入 cmd,即可启动命令窗口 2、输入 netstat -ano 命令查看当前系统的所有端口的使用情况 C:\Users\Administrator> netstat -ano 活动连接 协议 本地地址 外部地址 状态 PID TCP 0.0.0.0:135 0.0.0.0:0

王廷云的博客 2488

Linux聊天软件答辩PPT

一个聊天软件的本科毕业答辩ppt,Linux下的局域网聊天软件

网络聊天答辩

C++20协程深度解析:从原理到异步网络编程实战

协程是一种轻量级的用户态线程,它允许函数在执行过程中暂停和恢复,从而在不阻塞线程的情况下实现并发。其核心原理在于通过编译器生成状态机来管理函数的执行上下文,使得程序能够在等待I/O等操作时主动让出CPU,提高系统资源利用率。这项技术的核心价值在于将复杂的异步回调逻辑转化为直观的顺序执行代码,极大提升了代码的可读性和可维护性。在应用场景上,协程特别适合处理高并发的网络服务、文件I/O等I/O密集型任务,能有效解决传统异步编程中的“回调地狱”问题。本文以C++20协程为例,深入剖析其Promise Type、C

weixin_29268267的博客 279

火星遥感数据的获取与处理工具安装详解

有关火星遥感影像数据的那些事...

FengYingLuo的博客 5570

Linux C/C++网络编程实战-陈硕-笔记20-使用非阻塞IO

基于IO复用(非阻塞IO)实现的 netcat 使用非阻塞IO可以有效避免上述情况的发生。但非阻塞IO在编程上要比阻塞IO更难,并且在程序的维护上比较痛苦。一般使用非阻塞IO编程时建议使用一些封装好的网络库比较容易编写。 代码 recipes/python/netcat-nonblock.py netcat-nonblock#!/usr/bin/python import errno import fcntl import os import select import socket import s

AnitaSun的博客 605

开漏输出(漏极开路输出与集电极开路输出)和推挽输出怎么判断

判断一个引脚是还是。

weixin_56838517的博客 1055

c语言压力变送器程序设计,基于单片机的压力变送器设计

基于单片机的压力变送器设计(任务书,开题报告,外文翻译,论文15000字,代码)摘要随着工业化水平的不断提高,新型智能仪表在工业生产过程中运用也越来越广泛,同时对输出数据的准确检测和处理也变得至关重要。生产过程的运行和设备安全是极其重要的,那么如何实现对其精确的检测呢?众所周知,在工业生产过程中有一个很重要参数——压力,显然这个参数是一个必不可少的条件。故而,研究智能压力变松器系统对工业生产有着不...

weixin_33681561的博客 1962

初学 C 语言没有项目练手?这 20 个小项目拿走不谢~

C 语言是大多数人的编程入门语言,但很多初学者在学习的过程中难免会出现一些迷茫,比如:不知道 C 语言可以开发哪些项目,可以应用在哪些实际的开发中……今天我们收集了 20 个 C 语言练...

实验楼 2576

【ROS】Nav2源码之nav2_collision_monitor(碰撞监测)详解

nav2_collision_monitor碰撞监视器是一个节点,为机器人提供了一个额外的安全级别。它使用来自传感器的数据,执行若干与避免碰撞相关的任务,绕过成本图和轨迹规划器,监测是否需要紧急停止或者减速。

郭老二 1455

C++20协程异步编程的未来与实战解析

C++20协程通过无栈协程(stackless coroutines)实现,以co_await、co_yield和co_return关键字为核心。与传统回调函数和future/promise模式相比,协程提供了更直观的同步式编程风格,同时保持异步操作的性能优势。随着编译器优化(如MSVC、GCC、Clang)持续改进,协程性能将进一步提升,有望成为高并发服务的主流开发范式,特别是在云计算、游戏引擎和物联网领域。同时,应避免在协程内执行阻塞操作,以确保调度器效率。建议采用RAII模式管理资源,通过。

lawczj的博客 445

自然语言处理在智能客服系统中的应用

引言与背景 1.1 书籍的目的和内容概述 《自然语言处理在智能客服系统中的应用》旨在探讨自然语言处理(NLP)技术在智能客服系统中的应用,帮助读者理解NLP的核心概念及其在解决实际业务问题中的关键作用。随着人工智能技术的快速发展,自然语言处理成为构建智能客服系统的核心模块之一。本书将深入解析NLP

AI天才研究院 966

基于simulink的车道保持辅助系统(LKA)的仿真与实现

本文介绍了如何利用Simulink实现车道保持辅助系统(LKA)的仿真与建模。首先对比了车道偏离预警(LDW)和LKA的功能差异,强调LKA的主动干预特性。接着详细阐述了LKA系统架构,包括环境感知、决策控制等核心组件,并基于自行车模型建立车辆横向动力学方程。 文章重点演示了Simulink建模步骤:搭建车辆动力学模型、设计LKA控制器(采用LQR算法)、实现执行器接口和驾驶员干预检测。通过四个典型场景的仿真测试,验证了系统在直道行驶、弯道跟踪等工况下的控制性能,并给出了关键评价指标。最后展望了MPC控制、

amy_mhd的博客 226

C++20 协程:异步编程的新纪元

C++20 引入了协程(coroutines),这是一种全新的异步编程模型,使得编写异步代码变得更加简洁和直观。本文将详细介绍 C++20 协程的概念、功能演变及其在实际项目中的应用。通过本文,你将了解到协程的基本原理、语法和如何利用协程来简化异步编程。

jianglq的博客 1504

基于STM32设计的环境监测系统(华为云IOT)_300

随着空气污染问题日益严峻,环境空气质量的监测变得愈加重要。为了解决这一问题,本项目设计并实现了一款基于STM32的空气质量监测设备,能够实时监测空气中的温湿度、二氧化碳浓度和甲醛浓度,并通过OLED显示屏展示数据。此外,设备支持通过WIFI模块将数据上传至云端,用户可以通过手机APP或Windows上位机查看实时数据。设备采用MQTT协议与华为云IOT物联网服务器进行数据通信,确保数据的实时性和可靠性。本项目还结合了低功耗设计和高灵敏度传感器,使得设备能够高效稳定地运行,并实现远程监控功能。

695

20天学会Python!Python编程基础+Python编程高阶+Python编程实战

零基础学编程,用Python入门是个不错的选择,今天整理了Python从入门到精通的书籍该文档全面、系统、深入地讲解了Python编程基础语法与高级应用。在讲解过程中,通过大量实际操作的实例将Python 语言知识全面、系统、深入地呈现给读者。经作者多年的培训和授课证明,以上讲解方式是最适合初学者学习的方式,读者按照这种方式学习会非常轻松、顺利地掌握本书知识。

xnxqwzy的博客 862

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

java题目练习笔记,java 20道、数量关系8道、判断推理8道、智力题8道

java题目练习笔记,java 20道、数量关系8道、判断推理8道、智力题8道 一.java20道 1.Java Application 中的主类需包含main方法,以下哪项是main方法的正确形参?( ) String args String[] args Char arg StringBuffer[] args 解析:main函数的形式为public static void main(String[] args),所以选B 2.设有下面两个类的定义: 类Person和类Student的关系

m0_46546626的博客 1261

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: 19、多线程简介
下一篇: 21、注解和反射
coder_lcw
博客等级 码龄7年 22粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值