Linux下socket例子(c/c++)

Linux中的socket

    • 服务端逻辑
    • 客户端逻辑
    • c实现
    • c++实现
      • 服务端持续接收请求
      • 多线程实现
    • UDP实现

参考

服务端逻辑

  1. 创建service_sock
  2. 创建sockaddr_in结构体变量serv_addr,写明端口和ip
  3. 将socket和结构体绑定
  4. 监听socket
  5. 创建客户端sockaddr_in结构体变量clnt_addr
  6. 接收客户端请求,创建新的clnt_sock,客户端信息保存在clnt_addr中
  7. 向客户端发送数据
  8. 关闭clnt_sock
  9. 关闭serv_sock

客户端逻辑

  1. 创建sock
  2. 创建sockaddr_in结构体变量serv_addr,写明端口和ip
  3. 将socket和serv_addr作为参数,调用connect方法
  4. 调用read方法,读取服务端传来的数据
  5. 关闭sock

c实现

clien.c

#include <stdio.h>     //printf,sprintf,perror 相关声明在此文件中
#include <string.h>    //memset,strlen
#include <unistd.h>    //close
#include <arpa/inet.h> //sockaddr_in,socket,AF_INET,SOCK_STREAM,htons,inet_addr,connect,sockaddr,send,recv //相关定义和声明在此文件中#define MAX_CONN 2
#define BUF_SIZE 1024
#define PORT 9000int main(int argc, char *argv[])
{printf("argc is %d \n", argc);int i;for (i = 0; i<argc; i++){printf("arcv[%d] is %s\n", i, argv[i]);}struct sockaddr_in server_sai;int sfd = 0, res = -1, recvbytes = 0, sendbytes = 0;char buf[BUF_SIZE], buf2[5] = {0}; // 进行变量的定义和初始化if (argc < 3) // 如果参数小于3个就报错,命令后面会分别加上IP地址和消息内容,所以一共是三个参数{printf("error number of argc:%d\n", argc);return res;}memset(buf, 0, sizeof(buf)); // 对buf清零sprintf(buf, "%s", argv[2]); // 将要传输的内容(第二个参数)复制到buf中if (-1 == (sfd = socket(AF_INET, SOCK_STREAM, 0))) // 创建一个IPV4的TCP socket{perror("socket");return res;}server_sai.sin_family = AF_INET;                                // IPV4 协议族server_sai.sin_port = htons(PORT);                              // 9000端口server_sai.sin_addr.s_addr = inet_addr(argv[1]);                // 使用第一个参数作为IP地址memset(&(server_sai.sin_zero), 0, sizeof(server_sai.sin_zero)); // 将结构体剩余部分填零if (-1 == connect(sfd, (struct sockaddr *)&server_sai, sizeof(struct sockaddr))) // 使用sfd进行连接{perror("connect");return res;}if (-1 == (sendbytes = send(sfd, buf, strlen(buf), 0))) // 将buf中的内容写到远端服务端,buf中的内容是命令行中的第二个参数{perror("send");return res;}recvbytes = recv(sfd, buf2, 5, 0);     // 从服务端接收数据,写到buf2中printf("%d -->%s\n", recvbytes, buf2); // 将buf2中的数据显示出来close(sfd);                            // 进行清理工作,关闭描述符res = 0;return res;
}

server.c

#include <stdio.h>      //perror,printf 相关函数在此声明
#include <netinet/in.h> //sockaddr_in,htons,htonl,socket,AF_INET,SOCK_STREAM,INADDR_ANY,SOL_SOCKET,SO_REUSEADDR,bind,listen,accept,recv,send 相关声明和定义在这个文件中
#include <string.h>     //memset 相关函数在此声明
#include <unistd.h>     //close 相关函数在此声明#define MAX_CONN 2
#define BUF_SIZE 1024
#define PORT 9000int main()
{struct sockaddr_in server_sai, client_sai;int sfd = 0, cfd = 0, res = -1, on = 1, recvbytes = 0, sendbytes = 0;int addrlen = sizeof(struct sockaddr);char buf[BUF_SIZE]; // 各种变量定义与初始化if (-1 == (sfd = socket(AF_INET, SOCK_STREAM, 0))) // 创建一个IPV4的TCP socket{perror("socket");return res;}server_sai.sin_family = AF_INET;                                // IPV4 协议族server_sai.sin_port = htons(PORT);                              // 9000端口server_sai.sin_addr.s_addr = htonl(INADDR_ANY);                 // 0.0.0.0 的通配监听memset(&(server_sai.sin_zero), 0, sizeof(server_sai.sin_zero)); // 将剩余部分填零setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));     // closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socketif (-1 == bind(sfd, (struct sockaddr *)&server_sai, sizeof(struct sockaddr))) // 将 sfd 和 socket 地址进行绑定{perror("bind");return res;}if (-1 == (listen(sfd, MAX_CONN))) // 在sfd上进行监听,最多允许同时有2个请求在队列中排队,此配置正是DDOS的攻击点,协议天然的缺陷在于,不论这个值设多设少,都不会是一个适合的值{perror("listen");return res;}elseprintf("Listening...\n");if (-1 == (cfd = accept(sfd, (struct sockaddr *)&client_sai, (socklen_t *)&addrlen))) // 接受连接,将返回的描述符赋给cfd{perror("accept");return res;}memset(buf, 0, sizeof(buf)); // 将缓存置零if (-1 == (recvbytes = recv(cfd, buf, BUF_SIZE, 0))) // 从对端接受内容并且存到buf中{perror("recv");return res;}printf("Received a message:%s\n", buf); // 将收到的内容输出if (-1 == (sendbytes = send(cfd, "OK", 2, 0))) // 给客户端回复一个ok{perror("send");return res;}close(sfd);close(cfd); // 进行清理,关闭打开的描述符res = 0;return res;
}

c++实现

clien.cpp

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){//创建套接字int sock = socket(AF_INET, SOCK_STREAM, 0);//向服务器(特定的IP和端口)发起请求struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充serv_addr.sin_family = AF_INET;  //使用IPv4地址serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址serv_addr.sin_port = htons(1234);  //端口connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));//读取服务器传回的数据char buffer[40];read(sock, buffer, sizeof(buffer)-1);printf("Message form server: %s\n", buffer);//关闭套接字close(sock);return 0;
}

server.cpp

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
int main(){//创建套接字int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//将套接字和IP、端口绑定struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充serv_addr.sin_family = AF_INET;  //使用IPv4地址serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址serv_addr.sin_port = htons(1234);  //端口bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));//进入监听状态,等待用户发起请求listen(serv_sock, 20);//接收客户端请求struct sockaddr_in clnt_addr;socklen_t clnt_addr_size = sizeof(clnt_addr);int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);// 打印收到的客户端地址端口信息std::cout << "Client address: " << inet_ntoa(clnt_addr.sin_addr) << ", port: " << ntohs(clnt_addr.sin_port) << std::endl;//向客户端发送数据char str[] = "http://c.biancheng.net/socket/";write(clnt_sock, str, sizeof(str));//关闭套接字close(clnt_sock);close(serv_sock);return 0;
}

服务端持续接收请求

服务端持续接收客户端请求,其实就是加了个while循环

#include <arpa/inet.h>
#include <iostream>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
int main() {//创建套接字int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//将套接字和IP、端口绑定struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充serv_addr.sin_family = AF_INET;           //使用IPv4地址serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址serv_addr.sin_port = htons(1234);                   //端口bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));//进入监听状态,等待用户发起请求listen(serv_sock, 20);while (true) {//接收客户端请求struct sockaddr_in clnt_addr;socklen_t clnt_addr_size = sizeof(clnt_addr);int clnt_sock =accept(serv_sock, (struct sockaddr *)&clnt_addr, &clnt_addr_size);// 打印收到的客户端地址端口信息std::cout << "Client address: " << inet_ntoa(clnt_addr.sin_addr)<< ", port: " << ntohs(clnt_addr.sin_port) << std::endl;//向客户端发送数据char str[] = "http://c.biancheng.net/socket/";write(clnt_sock, str, sizeof(str));//关闭套接字close(clnt_sock);}close(serv_sock);return 0;
}

多线程实现

client.cpp

#include <arpa/inet.h>
#include <arpa/inet.h>
#include <errno.h>
#include <error.h>
#include <iostream>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
void *recvsocket(void *arg) //接受来自服务端数据的线程
{int st = *(int *)arg;char s[1024];while (1) {memset(s, 0, sizeof(s));int rc = recv(st, s, sizeof(s), 0);if (rc <= 0) //代表socket被关闭(0)或者出错(-1){break;}printf("client receive:%s\n", s);}return NULL;
}
void *sendsocket(void *arg) //向服务端socket发送数据的线程
{int st = *(int *)arg;char s[1024];while (1) {memset(s, 0, sizeof(s));scanf("%s", s);int sc = send(st, s, strlen(s), 0);}
}
//执行 ./ClientLinux.out 127.0.0.1 8080
int main(int arg, char *args[]) {if (arg < 3) {printf("arg<3\n");return -1;}int port = atoi(args[2]);//第一步:初始化一个socket实例int st = socket(AF_INET, SOCK_STREAM, 0);//第二步:定义一个IP地址结构并设置值struct sockaddr_in addr;//内存初始化,将addr变量指向的内存签n个字节用0进行初始化填充memset(&addr, 0, sizeof(addr));//设置采用的协议为TCP/IP协议addr.sin_family = AF_INET;//设置端口号addr.sin_port = htons(port);//设置IP地址addr.sin_addr.s_addr = inet_addr(args[1]);//第三步:开始连接服务端if (connect(st, (struct sockaddr *)&addr, sizeof(addr)) == -1) {printf("connect fail %s\n", strerror(errno));return EXIT_FAILURE;}//第四步:初始化要发送的信息并且通过send函数发送数据pthread_t thrd1, thrd2; //定义一个线程pthread_create(&thrd1, NULL, recvsocket, &st);pthread_create(&thrd2, NULL, sendsocket, &st);std::cout << "thrd1=" << thrd1 << std::endl;std::cout << "thrd2=" << thrd2 << std::endl;pthread_join(thrd1, NULL);pthread_join(thrd2, NULL);close(st);getchar();return EXIT_SUCCESS;
}

server.cpp

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include<arpa/inet.h>
#include <error.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
void* recvsocket(void* arg)//接受来着客户端数据的线程
{int st = *(int*)arg;char s[1024];while (1){memset(s, 0, sizeof(s));int rc = recv(st, s, sizeof(s), 0);if (rc <= 0)//代表socket被关闭(0)或者出错(-1){printf("sercver recv fail:%d\n", rc);break;}printf("server receive:%s\n", s);}return NULL;
}
void* sendsocket(void* arg)//向客户端socket发送数据的线程
{int st = *(int*)arg;char s[1024];while (1){memset(s, 0, sizeof(s));scanf("%s", s);int sc = send(st, s, strlen(s), 0);}
}
//执行命令 ./ServerLinux.out 8080
int main(int arg, char* args[])
{if (arg < 2){return -1;}int port = atoi(args[1]);int st = socket(AF_INET, SOCK_STREAM, 0);//setsockopt 设置socket的一个属性,让地址可以重用。int on = 0;if (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1){printf("setsockopt failed:%s\n", strerror(errno));return EXIT_FAILURE;}struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(port);//INADDR_ANY表示这个服务器上的所有Ip地址。一台服务器可以有多个ip地址。将socket绑定到这个机器的所有ip地址上addr.sin_addr.s_addr = htonl(INADDR_ANY);//将ip地址与server程序绑定if (bind(st, (struct sockaddr*) & addr, sizeof(addr)) == -1){printf("bind fail %s\n", strerror(errno));return EXIT_FAILURE;}//server开始监听。 20代表同时有多少个连接过来(20并发)if (listen(st, 20) == -1){printf("listen fail %s\n", strerror(errno));return EXIT_FAILURE;}//char s[1024];int client_st = 0;//客户端socketstruct sockaddr_in client_addr;//客户端IPpthread_t thrd1, thrd2;//定义一个线程while (1){memset(&client_addr, 0, sizeof(client_addr));socklen_t len = sizeof(client_addr);//accept会阻塞,直到有客户端连接过来。accept返回客户端的描述符client_st = accept(st, (struct sockaddr*) & client_addr, &len);if (client_st == -1){printf("accept fail %s\n", strerror(errno));return EXIT_FAILURE;}//打印客户端的ip地址printf("accept ip : %s\n", inet_ntoa(client_addr.sin_addr));pthread_create(&thrd1, NULL, recvsocket, &client_st);pthread_create(&thrd2, NULL, sendsocket, &client_st);}close(st);getchar();
}

UDP实现

udpclient.cpp

#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>#define BUF_SIZE 100
int main() {//创建套接字int sock = socket(PF_INET, SOCK_DGRAM, 0);//服务器地址信息struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充serv_addr.sin_family = PF_INET;serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");serv_addr.sin_port = htons(1234);//不断获取用户输入并发送给服务器,然后接受服务器数据struct sockaddr_in fromAddr;socklen_t addrLen = sizeof(fromAddr);while (1) {char buffer[BUF_SIZE] = {0};printf("Input a string: ");fgets(buffer, BUF_SIZE, stdin);sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr *)&serv_addr,sizeof(serv_addr));int strLen = recvfrom(sock, buffer, BUF_SIZE, 0,(struct sockaddr *)&fromAddr, &addrLen);buffer[strLen] = 0;printf("Message form server: %s\n", buffer);}close(sock);return 0;
}

udpserver.cpp

#include <arpa/inet.h>
#include <iostream>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>#define BUF_SIZE 100
int main() {//创建套接字int serv_sock = socket(AF_INET, SOCK_DGRAM, 0);//绑定套接字struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr));      //每个字节都用0填充serv_addr.sin_family = PF_INET;                //使用IPv4地址serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //自动获取IP地址serv_addr.sin_port = htons(1234);              //端口bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));//接收客户端请求struct sockaddr_in clnt_addr; //客户端地址信息socklen_t clnt_addr_size = sizeof(clnt_addr);char buffer[BUF_SIZE]; //缓冲区while (1) {int strLen = recvfrom(serv_sock, buffer, BUF_SIZE, 0,(struct sockaddr *)&clnt_addr, &clnt_addr_size);//打印客户端的ip地址printf("accept ip : %s\n", inet_ntoa(clnt_addr.sin_addr));char message[] = "I am server !";sendto(serv_sock, message, strlen(message), 0, (struct sockaddr *)&clnt_addr,clnt_addr_size);// sendto(serv_sock, buffer, strLen, 0, (struct sockaddr *)&clnt_addr,//        clnt_addr_size);}close(serv_sock);return 0;
}

socket通信过程中,读/写和单线程/多线程中都会存在阻塞问题,可以根据输出验证。比如上面注释的一行sendto,反注释掉的话,会交替打印两个send信息。

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

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

相关文章

【计算机网络笔记】路由算法之链路状态路由算法

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

Using Set Processing Effectively 有效地使用集合处理

Using Set Processing Effectively 有效地使用集合处理 The information in the topics that follow applies if you are developing new or upgrading older Application Engine programs to adhere to a set-based model. 如果要开发新的应用程序引擎程序或升级旧的应用程序…

k8s部署elk8 直接通过logstash获取日志文件方式

配置文件 kibana [rootnode101 config]# cat kibana.yml # # ** THIS IS AN AUTO-GENERATED FILE ** ## Default Kibana configuration for docker target server.host: "0.0.0.0" server.shutdownTimeout: "5s" elasticsearch.hosts: [ "http:/…

CSS中4种关系选择器

元素(标签)之间的关系 父元素&#xff1a;直接包含子元素的元素 子元素&#xff1a;直接被父元素包含的元素 祖先元素&#xff1a;直接或间接包含后代元素的元素&#xff0c;父元素也是祖先元素 后代元素&#xff1a;直接或间接被祖先元素包含的元素&#xff0c;子元素也是后代…

C++二分算法:找到最接近目标值的函数值

本文涉及的基础知识点 二分查找算法合集 题目 Winston 构造了一个如上所示的函数 func 。他有一个整数数组 arr 和一个整数 target &#xff0c;他想找到让 |func(arr, l, r) - target| 最小的 l 和 r 。 请你返回 |func(arr, l, r) - target| 的最小值。 请注意&#xff0c…

基于 Junit 的接口自动化测试框架实现!

分层的自动化测试 5~10 年前&#xff0c;我们接触的自动化测试更关注的是 UI 层的自动化测试&#xff0c;Mercury 的 WinRunner/QTP 是那个时代商业性自动化测试产品的典型代表&#xff0c;在那个时代大家单纯想的都是能用一个自动化操作的工具替代人力的点击&#xff0c;商业…

【教3妹学编辑-mysql】详解数据库三大范式

什么是范式 简单地理解就是&#xff1a;数据库设计时遵循的规范 三大范式 数据库三大范式包含&#xff1a;1、第一范式(1NF)&#xff1b;2、第二范式(2NF)&#xff1b;3、第三范式(3NF)。其中&#xff0c;第一范式(1NF)的要求是属性不可分割&#xff0c;第二范式(2NF)的要求是…

Java基础-----正则表达式

文章目录 1.简介2.目的3.学习网站4.常用匹配字符5.String类中用到正则表达式的方法 1.简介 又叫做规则表达式。是一种文本模式&#xff0c;包括普通字符和特殊字符&#xff08;元字符&#xff09;。正则使用单个字符来描述、匹配一系列某个句法规则的字符串&#xff0c;通常用…

[架构之路-247]:目标系统 - 设计方法 - 软件工程 - 结构化方法的基本思想、本质、特点以及在软件开发、在生活中的应用

目录 前言&#xff1a; 一、什么是非结构化方法 1.1 什么是非结构化方法 1.2 非结构化方法的适用场合 二、什么是结构化方法 1.1 结构化方法诞生的背景&#xff1a;软件规模发展&#xff1a;大规模、复杂系统的需要 1.2 概述 1.3 主要特点与核心思想 三、结构化方法在…

【Web】Flask|Jinja2 SSTI

目录 ①[NISACTF 2022]is secret ②[HNCTF 2022 WEEK2]ez_SSTI ③[GDOUCTF 2023] ④[NCTF 2018]flask真香 ⑤[安洵杯 2020]Normal SSTI ⑥[HNCTF 2022 WEEK3]ssssti ⑦[MoeCTF 2021]地狱通讯 ①[NISACTF 2022]is secret dirsearch扫出/secret 明示get传一个secret ?…

Wireshark抓包:理解TCP三次握手和四次挥手过程

TCP是一种面向连接、端到端可靠的协议&#xff0c;它被设计用于在互联网上传输数据和确保成功传递数据和消息。本节来介绍一下TCP中的三次握手和四次挥手。 文章目录 1 TCP头部格式2 wireshark抓包分析2.1 SEQ和ACK2.2 三次握手2.3 四次挥手 3 程序 1 TCP头部格式 TCP头部占据…

如何进行数据结构的设计和实现?

数据结构的设计和实现 数据结构是计算机科学中至关重要的概念之一&#xff0c;它涉及如何组织和存储数据以便有效地进行操作。在软件开发中&#xff0c;数据结构的选择和设计直接影响了程序的性能、可维护性和可扩展性。在这篇文章中&#xff0c;我们将深入探讨如何进行数据结…

【FPGA】Verilog:实现 RS 触发器 | Flip-Flop | 使用 NOR 的 RS 触发器 | 使用 NAND 的 RS 触发器

目录 0x00 RS 触发器&#xff08;RS Flip-Flop&#xff09; 0x01 实现 RS 触发器 0x02 使用 NOR 的 RS 触发器 0x03 使用 NAND 的 RS 触发器 0x00 RS 触发器&#xff08;RS Flip-Flop&#xff09; 触发器&#xff08;Flip-Flop&#xff09;是一种带有时钟的二进制存储设备…

C/C++多级指针与多维数组

使用指针访问数组 指针类型的加减运算可以使指针内保存的首地址移动。 指针类型加n后。首地址向后移动 n * 步长 字节。 指针类型减n后。首地址向前移动 n * 步长 字节。 步长为指针所指向的类型所占空间大小。 例如&#xff1a; int *p (int *)100;p 1&#xff0c;结果为首…

Vue 2.0的源码构建

Vue.js 源码是基于 Rollup 构建的&#xff0c;它的构建相关配置都在 scripts 目录下。 1. 构建脚本 通常一个基于 NPM 托管的项目都会有一个 package.json 文件&#xff0c;它是对项目的描述文件&#xff0c;它的内容实际上是一个标准的 JSON 对象。 我们通常会配置 script …

Autox.js和Auto.js4.1.1手机编辑器不好用我自己写了一个编辑器

功能有 撤销 重做 格式化 跳转关键词 下面展示一些 内联代码片。 "ui"; ui.layout( <drawer id"drawer"><vertical><appbar><toolbar id"toolbar"title""h"20"/></appbar><horizontal b…

get_cli_args函数

CLI是"Command Line Interface"的缩写&#xff0c;中文意为"命令行界面"。它是一种与计算机进行交互的方式&#xff0c;用户通过键盘输入文本命令来执行特定的任务&#xff0c;而不是通过图形用户界面&#xff08;GUI&#xff09;进行操作。在命令行界面中…

P1734 最大约数和

P1734 最大约数和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 预处理出小于等于S的数的约数和&#xff0c;将一个数的值作为体积&#xff0c;这个数的约数和作为价值&#xff0c;之后01背包模板。 void solve() {int n; cin>>n;vector<array<int,2>> a…

Linux环境搭建(tomcat,jdk,mysql下载)

是否具备环境&#xff08;前端node&#xff0c;后端环境jdk&#xff09;安装jdk,配置环境变量 JDK下载 - 编程宝库 (codebaoku.com) 进入opt目录 把下好的安装包拖到我们的工具中 把解压包解压 解压完成&#xff0c;可以删除解压包 复制解压文件的目录&#xff0c;配置环境变量…

【opencv】debug报错HEAP CORRUPTION DETECTED

运行至第一句涉及矩阵运算的代码&#xff08;如cv::multiply&#xff09;时报错 HEAP CORRUPTION DETECTED: after Normal block (#45034) at 0x000001BDC586F0E0. CRT detected that the application wrote to memory after end of heap buffer.release下不会报错&#xff0…