学习记录——day30 网络编程 端口号port 套接字socket TCP实现网络通信

news2024/11/27 10:29:42

目录

一、端口号 port

二、套接字 socket

1、原理

2、socket函数介绍

三、TCP实现网络通信

1、原理

2、TCP通信原理图

3、TCP相关函数

1)bind 绑定

2)listen  监听

 3)accept 接收连接请求

 4)recv 接收

5)send 发送

 6)connect 连接请求

4、TCP服务器端代码实现

 5、TCP客服端代码实现

四、UDP实现网络通信

1、UDP网络通信模型

 2、UDP相关函数 recvfrom sendto

3、UDP服务器端代码实现

4、UDP客服端端代码实现

五、TCP和UDP基础通信模型注意事项


一、端口号 port

1、为了区分同一主机上的多个进程,使用端口号来进行处理

2、端口号是一个2字节的无符号整数存储,取值范围【0,65535】

3、网络通信中两个“地址”,主机的地址——IP,进程的地址——端口号;

4、特殊的端口号:0-1023     

        由系统默认应用程序占用,编程不可使用

TCP 21端口:FTP文件传输服务
TCP 23端口:TELNET终端仿真服务
TCP 25端口:SMTP简单邮件传输服务
TCP 110端口:POP3邮局协议版本3
TCP 80端口:HTTP超文本传输服务
TCP 443端口:HTTPS加密超文本传输服务
UDP 53端口:DNS域名解析服务
UDP 69端口:TFTP文件传输服务

特殊的端口函数,存储在linux中的 /etc/services文件中

5、编程可使用的:1024-49151   

        编程可使用的端口号

6、临时端口号:49152-65535

        客服端运行时动态选择的,编程时若未指定端口号,会分配临时端口号

二、套接字 socket

        相关帮助指令     man 2 socket     man 7 socket

1、原理

2、socket函数介绍

       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int socket(int domain, int type, int protocol);
       功能:为通信创建一个端点,并返回该端点的文件描述符
       参数1:通信域
       Name                Purpose                          Man page
       AF_UNIX, AF_LOCAL   本地通信,同一主机之间进程通信     详情请看man 7 unix
       AF_INET             IPv4 提供的网络通信               详情请看man 7 ip
       AF_INET6            IPv6 提供的网络通信               详情请看man 7 ipv6
       参数2:指定通信语义,可以由多个宏值使用位或连接
       SOCK_STREAM:表示提供TCP协议的传输方式
       SOCK_DGRAM:表示提供UDP协议的传输方式
       SOCK_NONBLOCK:套接字设置非阻塞属性
       参数3:如果参数2中仅仅指定一个协议,那么参数3可以填0,如果指定多个,则参数3需要指定特定的协议
           TCP协议名称:IPPROTO_TCP
           UDP协议名称:IPPROTO_UDP
       返回值:成功返回创建的套接字文件描述符,失败返回     -1并置位错误码                 

三、TCP实现网络通信

1、原理

服务器端:

                1)创建套接字1

                2)给套接字1绑定服务器端端口号、ip地址

                3)将套接字1的功能改为监听(套接字内部被改造,原本的收发缓冲区改为已连接、未连接队列),用于检测是否客服端连接(三次握手就发生在这一步)

                4)阻塞等待连接,连接成功,创建套接字2,用于消息的收发

                5)消息的发送与接收

                6)关闭通信,可以由服务器端、客服端其中之一执行

客服端:

                1)创建由于通信的套接字

                2)绑定客服端端口号、ip地址

                3)连接服务器端,连接成功进入未连接队列,马上从未连接队列向已连接队列转换,该过程非常迅速,但同时申请连接的数量过多(超过未连接队列大小)仍会阻塞

                4)消息的发送与接收

                5)关闭通信,可以由服务器端、客服端其中之一执行

2、TCP通信原理图

3、TCP相关函数

1)bind 绑定

       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int bind(int sockfd, const struct sockaddr *addr,
 socklen_t addrlen);
       功能:位套接字分配名称
       参数1:通过socket函数创建出来的套接字文件描述符
       参数2:通用地址信息结构体,需要根据具体使用的地址族而定, struct sockaddr仅仅只是为了类型的强制转换,防止出现警告
           跨主机间通信:man 7 ip
            struct sockaddr_in {
               sa_family_t    sin_family; /* 表示通信域 */
               in_port_t      sin_port;   /* 端口号的网络字节序 */
               struct in_addr sin_addr;   /* ip地址 */
           };

           /* Internet address. */
           struct in_addr {
               uint32_t       s_addr;     /* IP地址的网络字节序 */
           };
           同一主机间通信:man 7 uninx
          struct sockaddr_un {
               sa_family_t sun_family;               /* 表示通信域:AF_UNIX */
               char        sun_path[108];            /* 套接字文件的地址 */
           };

        参数3:参数2的大小
        返回值:成功返回0,失败返回-1并置位错误码
 注意关于bind的两个错误:
 1、 Cannot assign requested address:表示IP地址填写错误,检查IP是否有问题
 2、Address already in use:表示地址信息正在占用,可以调用函数快速重用,也可以等一会

2)listen  监听

       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int listen(int sockfd, int backlog);
       功能:将套接字设置成被动监听状态,已接受客户端的连接请求
       参数1:套接字文件描述符
       参数2:容纳连接的队列的最大长度,一般填128
       返回值:成功返回0,失败返回-1并置为错误码
       

 3)accept 接收连接请求

       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
       功能:用于阻塞接收客户端连接请求
       参数1:服务器套接字文件描述符
       参数2:用于接收对端地址信息结构体的指针
       参数3:接收对端地址信息的长度
       返回值:成功返回一个新的用于通信的套接字文件描述符,失败返回-1并置位错误码

 4)recv 接收

       #include <sys/types.h>
       #include <sys/socket.h>

       ssize_t recv(int sockfd, void *buf, size_t len, int flags);
       功能:从套接字中读取数据到buf中
       参数1:用于通信的套接字文件描述符
       参数2:接收数据后的容器地址
       参数3:接收的数据的大小
       参数4:是否阻塞接收
              0:表示阻塞接收消息
              MSG_DONTWAIT:表示非阻塞接收数据
        返回值:
            >0:表示成功读取的字符个数
            =0:表示通信对端已经下线
            =-1:表示出错,置位错误码                    

5)send 发送

       #include <sys/types.h>
       #include <sys/socket.h>

       ssize_t send(int sockfd, const void *buf, size_t len, int flags);
       功能:向通信套接字文件描述符中写入数据
       参数1:通信的套接字文件描述符
       参数2:要发送数据的起始地址
       参数3:要发送数据的大小
       参数4:是否阻塞接收
              0:表示阻塞接收消息
              MSG_DONTWAIT:表示非阻塞接收数据
       返回值:成功返回发送字符的个数,失败返回-1并置位错误码       

 6)connect 连接请求

       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int connect(int sockfd, const struct sockaddr *addr,
 socklen_t addrlen);
       功能:将套接字文件描述符连接到addr指向的地址空间中
       参数1:客户端套接字文件描述符
       参数2:对端地址信息结构体
       参数3:参数2的大小
       返回值:成功返回0,失败返回-1并置位错误码

4、TCP服务器端代码实现

#include <myhead.h>
#define SER_PORT 6666
#define SER_IP "192.168.232.129"
int main(int argc, char const *argv[])
{
    // 1、创建套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    // 参数1:ipv4的网络通信
    // 参数2:TCP通信方式
    // 参数3:默认使用一个协议

    if (sfd == -1)
    {
        perror("socket error");
        return -1;
    }

    printf("socket success, sfd = %d\n", sfd); // 3

    // 2、为套接字绑定ip地址和端口号
    // 2.1 填充地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;                // 通信域
    sin.sin_port = htons(SER_PORT);          // 端口号
    sin.sin_addr.s_addr = inet_addr(SER_IP); // ip地址

    // 2.2 绑定
    if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");

    // 3、将套接字设置为被动监听状态,用于接收
    if (listen(sfd, 128) == -1)
    {
        perror("listen error");
        return -1;
    }
    printf("listen success\n");

    // 4、阻塞等待客户端的连接请求
    // 4.1 定义n变量用于e接收客服端的信息
    struct sockaddr_in cin;
    socklen_t addrlen = sizeof(cin);

    // 4.2 接收连接
    int newsfd = accept(sfd, (struct sockaddr *)&cin, &addrlen);
    if (newsfd == -1)
    {
        perror("accept error");
        return -1;
    }
    printf("[%s:%d]:accept on\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));

    //5、数据收发
    char buf[128] = "";

    while (1)
    {
        // 从客户端套接字中接收数据
        int res = recv(newsfd, buf, sizeof(buf),0);
        if (res == -1)
        {
            perror("read error");
            return -1;
        }
        else if (res == 0)
        {
            printf("客户端已下线\n");
            close(newsfd); // 关闭客户端套接字
            break;
        }

        // 接收数据
        printf("[%s:%d]:%s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);

        // 对接收到的数据进行处理
        strcat(buf, ":D");

        // 将消息返回到客户端
        if (send(newsfd, buf, strlen(buf),0) == -1)
        {
            perror("发送失败\n");
            return -1;
        }
        printf("发送成功\n");
        bzero(buf,sizeof(buf));//清空容器
    }
    return 0;
}

 5、TCP客服端代码实现

#include <myhead.h>
#define SER_PORT 6666            // 与服务器保持一致
#define SER_IP "192.168.232.129" // 服务器ip地址
#define CLI_PORT 8888            // 客服端端口号
#define CLI_IP "192.168.232.129" // 客服端ip地址
int main(int argc, char const *argv[])
{
    //1、 创建用于通信的套接字文件描述符
    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if (cfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("cfd = %d\n", cfd);
    //2、 绑定IP地址和端口号
    struct sockaddr_in cin;
    cin.sin_family = AF_INET;                // 通信域
    cin.sin_port = htons(CLI_PORT);          // 端口号
    cin.sin_addr.s_addr = inet_addr(CLI_IP); // ip地址

    //2.2、 绑定
    if (bind(cfd, (struct sockaddr *)&cin, sizeof(cin)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");
    //3、 连接服务器
    //3.1、 填充服务器地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET; //通信域
    sin.sin_port = htons(SER_PORT);
    sin.sin_addr.s_addr = inet_addr(SER_IP);

    //3.2、连接服务器
    if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
    {
        perror("connect error");
        return -1;
    }
    printf("连接服务器成功\n");

    //4、数据收发
    char buf[128] = "";
    while (1)
    {
        printf("输入:");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1] = 0;

        //将数据发送到服务器
        send(cfd,buf,strlen(buf),0);
        printf("发送结束\n");

        //接收服务器发送的数据
        bzero(buf,sizeof(buf));//清空容器
        recv(cfd,buf,sizeof(buf),0);
        printf("收到服务器信息:%s\n",buf);
    }
    
    //5、关闭套接字
    close(cfd);
    return 0;
}

四、UDP实现网络通信

1、UDP网络通信模型

 2、UDP相关函数 recvfrom sendto

       ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
       //功能:从套接字文件描述符中读取数据,并将对端地址信息结构体接收
       参数1:套接字文件描述符
       参数2:要接收数据的起始地址
       参数3:要接收的数据大小
       参数4:是否阻塞,0表示阻塞,MSG_NOWAIT表示非阻塞
       参数5:接收对端地址信息结构体
       参数6:参数5的大小
       返回值:成功返回读取的字节的大小,失败返回-1并置位错误码
       
        ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
      //功能:向套接字文件描述符中读取数据,写给指定的对端接收
       参数1:套接字文件描述符
       参数2:要发送数据的起始地址
       参数3:要发送的数据大小
       参数4:是否阻塞,0表示阻塞,MSG_NOWAIT表示非阻塞
       参数5:接收对端地址信息结构体
       参数6:参数5的大小
       返回值:成功返回发送的字节的大小,失败返回-1并置位错误码
                                             

3、UDP服务器端代码实现

#include <myhead.h>
#define SER_PORT 9999            // 服务器端口号
#define SER_IP "192.168.232.129" // 服务器ip地址
int main(int argc, char const *argv[])
{
    // 1、创建用于通信的套接字i文件描述符
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sfd == -1)
    {
        perror("scoket error");
        return -1;
    }
    printf("sfd = %d\n", sfd); // 3
    // 2、绑定ip地址和端口号
    //  2.1 填充地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;                // 通信域
    sin.sin_port = htons(SER_PORT);          // 端口号
    sin.sin_addr.s_addr = inet_addr(SER_IP); // ip地址

    // 2.2、 绑定
    if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");
    // 3、数据收发
    char buf[128] = "";

    struct sockaddr_in cin;          // 接收对端地址信息
    socklen_t addrlen = sizeof(cin); // 接收地址长度

    while (1)
    {
        // 清空容器
        bzero(buf, sizeof(buf));

        // 从套接字中读取数据
        recvfrom(sfd, buf, sizeof(buf), 0,(struct sockaddr*)&cin,&addrlen);
        printf("收到信息:%s\n", buf);

        // 处理收到的信息
        strcat(buf, ":(");

        if (sendto(sfd, buf, sizeof(buf), 0,(struct sockaddr*)&cin,sizeof(cin)) == -1)
        {
            perror("send error");
            return -1;
        }
        printf("发送成功\n");
    }

    // 4、关闭文件描述符
    close(sfd);
    return 0;
}

4、UDP客服端端代码实现

#include <myhead.h>
#define SER_PORT 9999            // 与服务器保持一致
#define SER_IP "192.168.232.129" // 服务器ip地址
#define CLI_PORT 5555            // 客服端端口号
#define CLI_IP "192.168.232.129" // 客服端ip地址
int main(int argc, char const *argv[])
{
    // 1、 创建用于通信的套接字文件描述符
    int cfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (cfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("cfd = %d\n", cfd);
    // 2、 绑定IP地址和端口号
    struct sockaddr_in cin;
    cin.sin_family = AF_INET;                // 通信域
    cin.sin_port = htons(CLI_PORT);          // 端口号
    cin.sin_addr.s_addr = inet_addr(CLI_IP); // ip地址

    // 2.2、 绑定
    if (bind(cfd, (struct sockaddr *)&cin, sizeof(cin)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");

    // 3、数据收发
    char buf[128] = "";

    // 3.1 填充服务器地址信息结构体
    struct sockaddr_in sin;                  // 接收对端地址信息
    sin.sin_family = AF_INET;                // 服务器的通信域
    sin.sin_port = htons(SER_PORT);          // 服务器的端口号
    sin.sin_addr.s_addr = inet_addr(SER_IP); // 服务器的ip地址

    while (1)
    {
        printf("输入:");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = 0;

        sendto(cfd, buf, strlen(buf), 0, (struct sockaddr *)&sin, sizeof(sin));

        printf("发送成功\n");

        bzero(buf, sizeof(buf));
        recvfrom(cfd, buf, sizeof(buf), 0, NULL, NULL);
        printf("收到服务器信息:%s\n", buf);
    }

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

五、TCP和UDP基础通信模型注意事项

1、无论时TCP还是UDP通信中,服务器必须绑定ip地址和端口号,以便于让客服端找到该服务器。对于客服端而言,ip地址和端口号可以不绑定,若不绑定,端口号由系统动态分配(49152-65535)

2、对于TCP通信而言,可以使用recv和send进行通信,也可以使用read、write进行通信,还可以使用sendto和recvfrom进行通信

3、对于UDP通信而言,如果当前端只是用于接收数据,不发送数据,可以使用recvfrom、recv、read进行接收;如果当前端接收数据后还要发送数据给对端,则需要使用recvfrom进行接收数据,以便接收对端地址信息结构体

4、UDP通信中,服务器端可以使用connect函数与指定的客服端建立一个唯一的通道,在解除这种连接前,其他客服端与服务器端间不能通信。可通过将与服务器端建立连接的那个客服端的地址消息结构体中的sin.family设置未 AF_UNSPEC, 后再次使用connect函数断开连接

        UDP中通信使用connect连接的好处:

                1)提高信息传输效率、完整度

                例如:A和B同时向服务器发送消息,但是A发送的消息较大,需要较长的时间,发送过程中可能会出现时间片用完,服务器转而接收B的消息的情况,这会导致消息混乱。这时就可以先单独跟A建立连接,等所有数据传输结束后,再跟B通信

                2)传输性能高

        一般的UDP通信:获取对端地址信息 -->将信息加载到内核 -->数据收发--->获取对端地址信息 -->将信息加载到内核 --->数据收发 --->获取对端地址信息 -->将信息加载到内核 -->数据收发 -->......

        会经历多次用户空间到内核空间的转换,该过程对于cpu而言是一个漫长的过程

        UDP建立连接后:获取对端地址信息 ->将信息加载到内核 ->数据收发 ->数据收发 >数据收发 >数据收发完成>进行其他对端的信息处理.....

        会有效的减少用户空间到内核空间的转换次数

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

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

相关文章

GitHub的常用操作

目录 GitHub GitHub加速 克隆GitHub上的项目到本地 克隆GitHub上指定分支的项目 把本地项目上传到GitHub上管理 删除分支里的内容 单个仓库管理多个项目 上传项目到新建的分支 目前正在逐步熟悉GitHub&#xff0c;打算把整理好的代码上传到GitHub上&#xff0c;建立属…

EasyRecovery17中文版本重磅发布更新!带你三分钟了最新功能

“你到底删了我什么&#xff1f;&#xff1f;” “我只是把聊天记录清理了下……” “你知不知道里面还有我发你的工作资料啊&#xff01;&#xff01;” …… 每当听到这种对话&#xff0c;我就知道又有人因为删错文件而和另一半/同事/领导吵起来了。 毕竟在这个手机电脑不离手…

超声波清洗机哪个牌子好?四款公认最好的超声波清洗机分享

随着生活水平的提高&#xff0c;人们对于生活有了更高的要求&#xff0c;而我们平时经常使用的一些小产品也要经常清理保持干净&#xff0c;所以针对于这些小产品&#xff0c;超声波清洁机应运而生。超声波清洗机&#xff0c;可能很多小伙伴见过或者使用过&#xff0c;它主要利…

多模态大语言模型的免训练视觉提示学习 ControlMLLM

ControlMLLM: Training-Free Visual Prompt Learning for Multimodal Large Language Models github paper 在本研究中&#xff0c;提出了一种无需进行训练的方法&#xff0c;通过可学习的潜变量优化将视觉提示注入到多模态大型语言模型&#xff08;MLLMs&#xff09;中。 在…

PPSSPP Gold 1.17 psp模拟器黄金版最新免费修改版

这是您在安卓设备上体验原汁原味PSP游戏魅力的最佳选择——唯一正版的PSP模拟器。借助它&#xff0c;您可以在高清画质下畅玩PSP游戏&#xff0c;并享受额外的功能特性。大多数游戏都能流畅运行&#xff0c;不过具体表现还需视您的设备性能而定&#xff0c;部分游戏可能无法达到…

【数据结构与算法】哈希表——字符串匹配

目录 一.引入二.哈希表结构三.SDBMHash算法(字符->数字)★四.哈希表的算法实现1.哈希函数2.初始化3.查找4.插入5.删除6.获取数据7.销毁 五.完整代码1.头文件2.源文件3.运行结果 一.引入 原来我们讲的都是以整数作为关键码,那么我们可不可以用字符串来作为关键码呢? 有的时…

如何选择适合自己的编程语言,为什么R是非计算机专业数据分析的最佳选择,五大点告诉你

在如今的数据驱动世界中&#xff0c;编程语言已成为希望在行业中进行数据分析的专业人士不可或缺的技能。对于非计算机专业背景的学者和学生来说&#xff0c;选择适合自己的编程语言可能看似困难。本文将探讨为什么对于那些需要进行本科生论文、研究生论文、或者发表学术成果的…

4款伪原创文章生成器软件,为创作者在线生成原创文章

在当今内容创作需求旺盛的时代&#xff0c;创作者们常常面临着时间紧迫、灵感枯竭等挑战。而伪原创文章生成器软件的出现&#xff0c;为创作者们提供了一定的帮助。以下将为你详细介绍4款具有特色的伪原创文章生成器软件。 1、智媒ai伪原创工具 对于创作者来说&#xff0c;这款…

redis模块和ioredis的注意事项

redis模块和ioredis的注意事项 文章目录 redis模块和ioredis的注意事项前言一、ioredis和redis使用zrange的比较二、出现zrange结果不同的原因总结 前言 node.js在使用redis的时候有两个库可以选择&#xff0c;一个是redis、另一个是ioredis&#xff0c;我一直以来也没有太大关…

小红书js逆向x-s之补环境

请求参数分析 数据文件在homefeed里&#xff0c;直接复制header参数在Convert curl commands 生成python代码跑一下 &#xff08;注意curlconverter生成的respond的输入参数里有一个是json&#xff0c;这个是不对的&#xff0c;需要改为data&#xff09; 结果发现报错&…

netcore-https证书配置

一、新建项目&#xff1a;WebHtpsDemo 二、生成pfx证书 拷贝到项目中 三、修改配置文件appsettings.Development.json {"KestrelSettings": {"IP": "192.168.31.68","Port": 8189,"CerPath": "xxxCert.pfx",&qu…

“艾”公益——微笑行动「文山站」为艾祝福,让笑起舞

艾多美“微笑行动”文山站拉开帷幕 此次爱心帮助71名唇腭裂患儿 重新绽放微笑 ♥ ♥ ♥ 不让笑容留有缺憾 每个孩子都有微笑的权利 艾多美向唇腭裂儿童伸出援手 绽放笑容&#xff0c;拥抱全新的未来 2024年8月6日-8月12日&#xff0c;云南省文山康复医院迎来了艾多美--微笑行动…

C语言典型例题35

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 例题3.3 有一函数&#xff1a;y{-1&#xff08;x<0&#xff09;;0(x0);1(x>0);编程序&#xff0c;要求输入一个x值后&#xff0c;输出y值。 代码&#xff1a; //《C程序设计教程&#xff08;第四版&#xff…

PaddleOCR 图片文字提取

PaddleOCR 图片文字提取 需求一.裁剪车牌号码区域二.对车牌小图进行处理三.填充边界四.识别步骤 需求 工作上的一个需求&#xff0c;需要把图片中的车牌号码提取出来。如图&#xff0c;车牌在图片固定位置。开始使用pytesseract&#xff0c;对中文识别特别不友好&#xff0c;毕…

19116 丑数

### 计划 1. **输入处理**&#xff1a;读取输入的正整数 T 和 T 行的正整数 n。 2. **生成丑数**&#xff1a;使用最小堆&#xff08;优先队列&#xff09;生成丑数&#xff0c;确保每次取出的数都是当前最小的丑数。 3. **存储丑数**&#xff1a;将生成的丑数存储在一个数组中…

IO网络编程

思维导图 作业一&#xff1a;使用wasd控制机械臂 #include<myhead.h> #include <termios.h> #define SER_PORT 8888 //与服务器保持一致 #define SER_IP "192.168.0.103" //服务器ip地址 #define CLI_PORT 6666 //客户端…

【网络】TCP拥塞窗口(第六篇)

拥塞窗口&#xff08;Congestion Window&#xff0c;简称cwnd&#xff09;是TCP协议中用于防止网络拥塞的一种重要机制。它是在发送端采用的一种“拥塞避免”算法和“慢速启动”算法相结合的机制&#xff0c;用于控制发送端向网络中注入的数据量&#xff0c;从而避免网络拥塞。…

MySQL数据库介绍及基础操作

目录&#xff1a; 一.数据库介绍 二.数据库分类 三. 数据库的操作 四. 常用数据类型 五. 表的操作 一.数据库介绍 1.文件保存数据有以下几个缺点: 1.1文件的安全性问题 1.2文件不利于数据查询和管理 1.3文件不利于存储海量数据 1.4文件在程序中控制不方便 为了解决上述问题&…

python爬取B站视频实验

实验17&#xff1a;爬虫2 文章目录 实验17&#xff1a;爬虫21.实验目标及要求2. 实验主要内容3.实验小结 1.实验目标及要求 &#xff08;1&#xff09;掌握有关爬虫的包 &#xff08;2&#xff09;掌握爬虫方法 &#xff08;3&#xff09;爬取B站卡塔尔世界杯若干视频 2. 实验…

css实现水滴效果图

效果图&#xff1a; <template><div style"width: 100%;height:500px;padding:20px;"><div class"water"></div></div> </template> <script> export default {data() {return {};},watch: {},created() {},me…