嵌入式养成计划-32-网络编程----域套接字模型------抓包工具--wireshark

news2025/2/25 8:52:05

六十九、 域套接字模型

69.1 域套接字的概念

  1. 只能做一台主机内的进程间通信,协议族(地址族)指定为:AF_UNIX AF_LOCAL
  2. bsp-lcd: s类型文件,就是域套接字
  3. 如果客户端不手动绑定,则操作系统不会创建一个套接字文件给客户端自动绑定的。

69.2 域套接字的函数使用

69.2.1 socket

功能:
    在内核空间中创建两个缓冲区(接收缓冲区,发送缓冲区),并返回缓冲区的文件描述(套接字文件描述符);
原型:
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int socket(int domain, int type, int protocol);
参数:
    int domain:地址族,协议族;
       Name                Purpose                          Man page
       AF_UNIX, AF_LOCAL   Local communication              unix(7)
                      
    int type:套接字类型
        SOCK_STREAM:字节流式套接字,流式套接字---》TCP协议
        SOCK_DGRAM: 数据报式套接字,报式套接字---》UDP协议
        SOCK_RAW:原始套接字,协议需要在第三个参数指定;
    
    int protocol:填0,代表使用默认协议;
        IPPROTO_TCP:TCP协议    IPPROTO_UDP:UDP协议;
返回值:
    >=0,套接字文件描述符;
    =-1,失败,更新errno;

69.2.2 bind

功能:
    绑定地址信息到指定套接字上;
原型:
    #include <sys/types.h>          /* See NOTES */
    #include <sys/socket.h>

    int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
参数:
    int sockfd:指定要绑定到哪个套接字上,填对应的文件描述符;
    struct sockaddr *addr:通用地址信息结构体,真实的地址信息结构体根据地址族指定。
                            手动填充上地址信息(例如:IP和端口),给bind函数绑定使用;
        AF_UNIX : man 7 unix 
           struct sockaddr_un {
               sa_family_t sun_family;		/* AF_UNIX */     必须填AF_UNIX
               char        sun_path[108];	/* pathname */    套接字文件路径名
											必须事先不存在,由bind函数生成
           };

    socklen_t addrlen:真实的地址信息结构体的大小,sizeof(struct sockaddr_un);
返回值:
    成功,返回0;
    失败,返回-1,更新errno;

69.2.3 access

功能:判断文件是否存在,或者文件是否有某种权限;
原型:

69.2.4 unlink

功能:删除文件(的硬链接)
原型:

69.3 流式域套接字

69.3.1 UNIX TCP服务器

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>

#define ERR_MSG(msg)  do{\
    fprintf(stderr, "__%d__:", __LINE__); \
    perror(msg);\
}while(0)

int main(int argc, const char *argv[])
{
    //创建流式套接字 socket
    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("socket create success sfd=%d\n", sfd);

    //判断套接字文件是否存在
    if(access("./unix", F_OK) == 0)
    {
        //若存在则删除该套接字文件
        unlink("./unix");
    }
    
    //填充地址信息结构体给bind函数绑定,
    //真实的地址信息结构体根据地址族指定 AF_UNIX:man 7 unix
    struct sockaddr_un sun;
    sun.sun_family      = AF_UNIX;      //必须填AF_UNIX;
    strcpy(sun.sun_path, "./unix");     //必须事先不存在,由bind函数生成
                                                                             
    //绑定服务器的地址信息---> 必须绑定 bind
    if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind success\n");

    //将套接字设置为被动监听状态 listen
    if(listen(sfd, 128) < 0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("listen success\n");

    int newfd = -1;
    struct sockaddr_un cun;             //存储客户端的地址信息
    socklen_t addrlen = sizeof(cun);    //真实的地址信息结构体的大小

    //获取一个已经完成的客户端信息,生成一个新的文件描述符 accept
    //newfd = accept(sfd, NULL, NULL);
    newfd = accept(sfd, (struct sockaddr*)&cun, &addrlen);
    if(newfd < 0)
    {
        ERR_MSG("newfd");
        return -1;
    }
    printf("[]客户端连接成功 newfd=%d\n", newfd);

    char buf[128] = "";
    ssize_t res = 0;
    while(1)
    {
        //清空字符串
        bzero(buf, sizeof(buf));    //memset

        //接收
        res = recv(newfd, buf, sizeof(buf), 0);
        if(res < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0 == res)
        {
            printf("[]客户端下线 newfd=%d\n", newfd);
            break;
        }
        printf("[] newfd=%d : %s\n", newfd, buf);

        //发送
        strcat(buf, "*_*");
        if(send(newfd, buf, sizeof(buf), 0) < 0)
        {
            ERR_MSG("send");
            return -1;
        }
        printf("send success\n");
    }

    //关闭文件名描述符
    close(newfd);
    if(close(sfd) < 0)
    {
        ERR_MSG("close");
        return -1;
    }

    return 0;
}

69.3.2 UNIX TCP客户端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>

#define ERR_MSG(msg)  do{\                                              
    fprintf(stderr, "__%d__:", __LINE__); \
    perror(msg);\
}while(0)

int main(int argc, const char *argv[])
{
    //创建流式套接字 socket
    int cfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(cfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("socket create success cfd=%d\n", cfd);

    //绑定客户端的地址信息---》非必须绑定
    //当不手动绑定的时候,操作系统会自动给客户端绑定本机IP和随机端口。

    //填充服务器的地址信息结构体给connect函数连接,
    //想连接哪个服务器,就填哪个服务器绑定的地址信息
    //真实的地址信息结构体根据地址族指定 AF_UNIX:man 7 unix
    struct sockaddr_un sun;
    sun.sun_family      = AF_UNIX;      //必须填AF_UNIX;
    strcpy(sun.sun_path, "./unix");     //服务器绑定的套接字文件

    //连接指定服务器 connect
    if(connect(cfd, (struct sockaddr*)&sun, sizeof(sun)) < 0)
    {
        ERR_MSG("connect");
        return -1;
    }
    printf("connect success\n");

    char buf[128] = "";
    ssize_t res = 0;
    while(1)
    {
        //清空字符串
        bzero(buf, sizeof(buf));    //memset
        printf("请输入>>> ");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = 0;

        //发送
        if(send(cfd, buf, sizeof(buf), 0) < 0)
        {
            ERR_MSG("send");
            return -1;
        }
        printf("send success\n");

        bzero(buf, sizeof(buf));    //memset
        //接收
        res = recv(cfd, buf, sizeof(buf), 0);
        if(res < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0 == res)
        {
            printf("服务器下线 cfd=%d\n", cfd);
            break;
        }
        printf("cfd=%d : %s\n", cfd, buf);

    }

    //关闭文件名描述符
    if(close(cfd) < 0)
    {
        ERR_MSG("close");
        return -1;
    }

    return 0;
}

69.4 报式域套接字

  1. 报式域套接字的编程与网络报式套接字编程思路是一致的,但是由于客户端不手动绑定的话,操作系统不会自动创建一个套接字文件给客户端绑定
  2. 此时若服务器想给客户端回复信息,会找不到客户端的地址信息。此时客户端是必须绑定的。

69.4.1 UNIX UDP服务器

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>

#define ERR_MSG(msg)  do{\
    fprintf(stderr, "__%d__:", __LINE__); \
    perror(msg);\
}while(0)

int main(int argc, const char *argv[])
{
    //创建报式套接字 socket
    int sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(sfd < 0)
    {
        ERR_MSG("socket");                                                             
        return -1;
    }
    printf("socket create success sfd=%d\n", sfd);

    //判断套接字文件是否存在 。 若存在则删除
    if(access("./myunix", F_OK) == 0)
    {
        unlink("./myunix");
    }

    //填充服务器的地址信息结构体,给bind函数使用
    //真实的地址信息结构体根据地址族指定,AF_UNIX:man 7 unix
    struct sockaddr_un sun;
    sun.sun_family      = AF_UNIX;      //必须填AF_UNIX;
    strcpy(sun.sun_path, "./myunix");   //必须事先不存在,由bind函数生成

    //绑定地址信息结构体--->bind
    if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind success\n");

    char buf[128] = "";
    struct sockaddr_un cun;     //存储发送方的地址信息;
    socklen_t addrlen = sizeof(cun);

    while(1)
    {
        bzero(buf, sizeof(buf));
        //接收数据
        if(recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cun, &addrlen) < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        printf("[%s] : %s\n", cun.sun_path, buf);

        //发送数据----->谁发给我,我发还给谁
        strcat(buf, "*_*");
        if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cun, sizeof(cun)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        printf("sendto success\n");
    }

    //关闭套接字
    close(sfd);
    return 0;
}

69.4.2 UNIX UDP客户端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>

#define ERR_MSG(msg)  do{\
    fprintf(stderr, "__%d__:", __LINE__); \
    perror(msg);\
}while(0)

int main(int argc, const char *argv[])
{
    printf("请输入套接字文件名>>> ");
    char sockname[20] = "";
    scanf("%s", sockname);

    while(getchar()!=10);
    //创建报式套接字 socket
    int cfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(cfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("socket create success cfd=%d\n", cfd);
    /*
    //绑定客户端的地址信息---》非必须绑定                                                        
    //若不绑定则操作系统不会自动给客户端绑定套接字文件
    //若udp服务器想要给客户端回复信息,则客户端必须绑定套接字文件
    */

    //填充客户端的地址信息结构体,给bind函数使用
    struct sockaddr_un cun;
    cun.sun_family      = AF_UNIX;
    strcpy(cun.sun_path, sockname);

    //绑定地址信息结构体--->bind
    if(bind(cfd, (struct sockaddr*)&cun, sizeof(cun)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind success\n");

    //填充服务器的地址信息结构体,给sendto函数使用
    //真实的地址信息结构体根据地址族指定,AF_UNIX:man 7 unix
    struct sockaddr_un sun;
    sun.sun_family      = AF_UNIX;      //必须填AF_UNIX;
    strcpy(sun.sun_path, "./myunix");   //服务器绑定的套接字文件

    char buf[128] = "";
    struct sockaddr_un rcvaddr;     //存储发送方的地址信息;
    socklen_t addrlen = sizeof(rcvaddr);

    while(1)
    {
        bzero(buf, sizeof(buf));
        //发送数据----->从终端获取数据发送给指定端
        printf("请输入>>> ");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = 0;

        if(strcmp(buf, "quit") == 0)
        {
            unlink(sockname);   //若客户端下线,则删除套接字文件
            break;
        }

        if(sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sun, sizeof(sun)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        printf("sendto success\n");

        //接收数据
        bzero(buf, sizeof(buf));
        if(recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&rcvaddr, &addrlen) < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        printf("[%s] : %s\n", rcvaddr.sun_path, buf);

    }

    //关闭套接字
    close(cfd);
    return 0;
}

七十、 抓包工具— —wireshark

70.1 wireshak安装

  1. 保存虚拟机中代码,因为wireshark安装可能导致计算机重启
  2. 安装wireshark,
  3. 可以修改安装路径到自定义路径
  4. 安装时候看到Desktop Icon选项,请勾选。其余都默认
  5. 安装完毕后,打开wireshark,若出现未找到接口字眼,说明安装失败。

70.2 wireshark使用

70.2.1 wireshark 抓包

  • 开始界面
  1. wireshark是捕获机器上的某一块网卡的网络包,当你的机器上有多块网卡的时候,你需要选择一个网卡。
  2. 双击需要的网卡,开始抓包
  • Wireshark 窗口介绍

在这里插入图片描述

70.2.2 wireshark与对应的OSI七层模型

在这里插入图片描述

  • 服务器和客户端的代码不能都运行在ubuntu,因为wireshark抓的是流经真实网卡的数据包。
  • 若将服务器客户端都运行在ubuntu,数据直接经过虚拟网卡通信,而不会经过真实网卡。
    在这里插入图片描述

70.3 包头分析

70.3.1 以太网头

以太网中封装了源mac地址以及目的mac地址,还有ip类型,以太网又称之为mac头
在这里插入图片描述

0X0800 只接收发往本机的mac的ipv4类型的数据帧
0X0806 只接收发往本机的ARP类型的数据帧
0x8035 只接受发往本机的RARP类型的数据帧
0X0003 接收发往本机的MAC所有类型:ip,arp,rarp数据帧,接收从本机发出去的数据帧,
混杂模式打开的情况下,会接收到非发往本地的MAC数据帧

70.3.2 IP头

在这里插入图片描述
IP头中需要掌握用于分帧的部分:id flags fregment_offset
两个IP地址:源IP与目的IP地址。
TTL:time to live, 指定数据帧可以最多经过几个路由器,每经过一个路由器TTL-1。当数据帧被目标方接收后,TTL清除为0.
​ 当TTL为0时,从网络中删除。

Linux TTL:64 Winodws:TTL 128

70.3.3 UDP头

在这里插入图片描述

70.3.4 TCP头

在这里插入图片描述

  1. 端口号
  2. SYN:握手包,连接时候出现
    PSH:数据传输包,在传输数据时候出现
    FIN:挥手包,在断开连接的时候出现
    ACK:应答包,用于应答 非应答包
  3. Seq:序列号,占4个字节,用于给数据段进行编号的。所有非应答包的数据段,都有seq。
    Ack:应答号,用于应答非应答包(握手包,挥手包,数据包)。告诉对方下一次从这个seq编号发送数据包。
  4. PSH Ack = Seq+len;
    SYN FIN Ack = Seq+1;
    在这里插入图片描述

70.3.5 三次握手(重点!!!)

  • 三次握手的发起方,肯定是客户端
    在这里插入图片描述
    在这里插入图片描述
  1. 第一次握手:客户端发送SYN包(SYN=1, seq=0)给服务器,并进入SYN_SENT状态,等待服务器返回确认包。
  2. 第二次握手:服务器接收到SYN包,确认客户端的SYN,发送ACK包(ACK=1 , ack=1),同时发送一个SYN包(SYN=1, seq=0),并进入SYN_RCVD状态。
  3. 第三次握手:客户端接收到服务器的SYN包,以及ACK包,进入establish状态,同时向服务器发送ACK包(ACK=1, ack=1)。此时三次握手包发送完毕,服务器也进入establish状态

70.3.6 四次挥手(重点!!!)

  • 四次挥手的发起方可能是服务器,也可能是客户端
    在这里插入图片描述
    在这里插入图片描述
  1. 第一次挥手,主动关闭方发送一个FIN包(FIN=1, seq = u)给被动方,进入FIN_WAIT_1状态;
  2. 第二次挥手:被动方接收到FIN包,给主动方发送一个ACK包(ACK=1, ack=u+1);并进入CLOKSE_WAIT状态。主动方接受到ACK包后,进入FIN_WAIT_2状态。如果有数据没有发送完毕,则继续发送,直到发送完毕为止;
  3. 第三次挥手:被动方发送一个FIN包(FIN=1, seq=w),进入LAST_ACK状态.
  4. 第四次挥手:主动关闭方收到FIN包,回复一个ACK包(ACK=1, ack=w+1)。被动关闭方收到主动关闭方的ACK后关闭连接。

笔试面试题型

  • 这几个问题问的都是同一个:三次握手四次挥手
1. 三次握手四次挥手流程。
2. 请简述TCP建立连接断开连接的过程。(三次握手,四次挥手)
3. 请简述TCP和UDP通信过程中的区别?(三次握手,四次挥手 ,有无应答)
4. 请简述如何用UDP模型实现TCP式传输?(三次握手,四次挥手 ,有无应答)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣刷题 day37:10-07

1.二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 方法一&#xff1a;二分法 #方法一&#xff1a;二分法 def…

数百个下载能够传播 Rootkit 的恶意 NPM 软件包

供应链安全公司 ReversingLabs 警告称&#xff0c;最近观察到的一次恶意活动依靠拼写错误来诱骗用户下载恶意 NPM 软件包&#xff0c;该软件包会通过 rootkit 感染他们的系统。 该恶意软件包名为“node-hide-console-windows”&#xff0c;旨在模仿 NPM 存储库上合法的“node-…

vue3+elementPlus ElMessageBox消息框取消按钮位置调整

要求所有的ElMessageBox消息弹出框的取消按钮放在右边&#xff0c;如图 代码如下 <script lang"ts" setup> import { ElMessageBox } from element-plus const btnHandle () >{ElMessageBox.confirm(确定要删除该人员吗&#xff1f;,提示,{cancelButtonCl…

嵌入式养成计划-35------C++绪论------C++数据类型------array容器------命名空间

七十三、 工具QT 73.1 安装步骤 73.2 什么是 Qt Qt 是一个跨平台的 C图形用户界面应用程序框架。 它为应用程序开发者提供建立艺术级图形界面所需的所有功能。 它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 73.3 Qt 的优点 跨平台&…

深入了解快速排序:原理、性能分析与 Java 实现

快速排序&#xff08;Quick Sort&#xff09;是一种经典的、高效的排序算法&#xff0c;被广泛应用于计算机科学和软件开发领域。本文将深入探讨快速排序的工作原理、步骤以及其在不同情况下的性能表现。 什么是快速排序&#xff1f; 快速排序是一种基于分治策略的排序算法&am…

【虚拟机栈】

文章目录 1. 虚拟机栈概述2. 局部变量表(Local Variables)3. 操作数栈4. 动态链接4.1 方法的调用&#xff1a;解析与分配 1. 虚拟机栈概述 每个线程在创建时都会创建一个虚拟机栈&#xff0c;其内部保存一个个的栈帧&#xff08;Stack Frame&#xff09;&#xff0c;对应着一次…

【Solidity】智能合约案例——①食品溯源合约

目录 一、合约源码分析&#xff1a; 二、合约整体流程&#xff1a; 1.部署合约 2.管理角色 3.食品信息管理 4.食品溯源管理 一、合约源码分析&#xff1a; Producer.sol:生产者角色的管理合约&#xff0c;功能为&#xff1a;添加新的生产者地址、移除生产者地址、判断角色地址…

阿里云轻量应用服务器流量价格表(计费/免费说明)

阿里云轻量应用服务器套餐有的限制月流量&#xff0c;有的不限制月流量&#xff0c;限制每月流量的套餐&#xff0c;如果自带的免费月流量包用完了&#xff0c;流量超额部分需要另外支付流量费&#xff0c;阿里云百科aliyunbaike.com分享阿里云轻量应用服务器月流量超额收费价格…

信号量机制实现进程互斥,进程同步,进程的前驱关系

信号量机制 一个信号量对应一种资源。 信号量的值这种资源的剩余数量&#xff08;信号量的值如果小于0&#xff0c;说明此时有进程在等待这种资源) P(S )&#xff1a;申请一个资源S&#xff0c;如果资源不够就阻塞等待V(S)&#xff1a;释放一个资源S&#xff0c;如果有进程在…

Linux 磁盘管理+实例

目录 一、文件系统 二、添加磁盘 三、查看磁盘信息&#xff08;块设备&#xff09; 四、分区 1、格式 1&#xff09;MBR分区 2&#xff09;GPT分区 2、管理分区 1&#xff09;使用fdisk 2&#xff09;使用gdisk 3&#xff09;使用parted a.交互式 b.非交互式 3、…

Django 前端模板显示换行符、日期格式

linebreaksbr 显示换行符 <td>{{ data.sku_list|default:"无"|linebreaksbr }}</td> date:"Y年m月d日 H:i" 设置日期格式 <td>{{ data.submit_time|date:"Y年m月d日 H:i" }}</td> 其他语法 forloop 获取循环的索引 …

CSP-J第二轮试题-2019年-3题

文章目录 参考&#xff1a;总结 [CSP-J2019] 纪念品题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示答案 现场真题注意事项 参考&#xff1a; P5662 CSP-J2019纪念品 总结 本系列为CSP-J/S算法竞赛真题讲解&#xff0c;会按照年…

[极客大挑战 2019]BabySQL 1

#做题方法# 进去之后做了简单的注入发现有错误回显&#xff0c;就进行注入发现过滤了sql语 后面进行了双写and payload&#xff1a; ?usernameadmin%27%20aandnd%20updatexml(1,concat(0x7e,dAtabase(),0x7e,version()),1)%20--&passwordadmi 接下来又 ?usernameadm…

Python大数据之PySpark(七)SparkCore案例

文章目录 SparkCore案例PySpark实现SouGou统计分析 总结后记 SparkCore案例 PySpark实现SouGou统计分析 jieba分词&#xff1a; pip install jieba 从哪里下载pypi 三种分词模式 精确模式&#xff0c;试图将句子最精确地切开&#xff0c;适合文本分析&#xff1b;默认的方…

华为云云耀云服务器L实例评测|部署私有网盘 Nextcloud

华为云云耀云服务器L实例评测&#xff5c;部署私有网盘 Nextcloud 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 产品规格1.3 应用场景 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Nextcloud3.1 Nextcloud 介绍3.2 Docker 环境搭建3.3 Nex…

趣味工具箱小程序源码

趣味工具箱小程序源码&#xff0c;支持功能去水印&#xff0c;精选壁纸&#xff0c;图片压缩&#xff0c;文字生成二维码&#xff0c;图片加水印&#xff0c;模拟来电&#xff0c;手持弹幕&#xff0c;掷骰子…等 使用小工具&#xff0c;一个小程序有几十个功能。 源码下载&am…

掌握 BERT:自然语言处理 (NLP) 从初级到高级的综合指南(1)

简介 BERT&#xff08;来自 Transformers 的双向编码器表示&#xff09;是 Google 开发的革命性自然语言处理 (NLP) 模型。它改变了语言理解任务的格局&#xff0c;使机器能够理解语言的上下文和细微差别。在本文[1]中&#xff0c;我们将带您踏上从 BERT 基础知识到高级概念的旅…

网络安全(黑客)——自学笔记

前言&#xff1a; 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“…

【React】深入理解React组件状态State

目录 一、何为State二、如何定义State三、如何判断是否为State四、如何正确使用State1、用setState修改State2、State的更新是异步的①、代码示例 3、State更新会被合并①、组件状态例子②、当只需要修改状态title时&#xff0c;只需要将修改后的title传给setState③、React会合…

Go 语言高级网络编程

深入探讨 Go 语言的网络编程 简介 Go&#xff08;Golang&#xff09;中的网络编程具有易用性、强大性和乐趣。本指南深入探讨了网络编程的复杂性&#xff0c;涵盖了协议、TCP/UDP 套接字、并发等方面的内容&#xff0c;并附有详细的注释。 关键概念 1. 网络协议 TCP&#x…