当前位置: 首页 > news >正文

TCP(TCP客户端、服务器如何通信)

一、TCP介绍

TCP的特点:

  1. 面向连接的协议:TCP是一种可靠的、面向连接的协议,在通信之前需要建立连接,以确保数据的可靠传输。这意味着在传输数据之前,发送方和接收方之间需要建立一条可靠的连接通道。
  2. 流式协议:TCP将数据看作是一连串的字节流,而不是独立的数据包。这意味着在传输过程中,数据可以被分割成多个数据包进行传输,并在接收端进行重新组装。
  3. 可靠传输:TCP通过使用校验和、序列号和确认应答等机制,确保数据的可靠传输。如果在传输过程中发生错误或丢失,TCP会进行重传,以确保数据的完整性和准确性。
  4. 出错重传:当TCP接收到错误的数据包时,它会要求发送方重新发送该数据包,以确保数据的正确性。
  5. 确认应答:TCP使用确认应答机制来确保数据的可靠传输。当接收方收到一个数据包时,它会向发送方发送一个确认应答,表示已经收到了该数据包。
  6. 服务器被动连接,客户端主动连接:在TCP连接中,服务器通常处于被动状态,等待客户端的连接请求。而客户端则处于主动状态,负责发起连接请求。一旦连接建立成功,双方就可以进行数据传输。  

TCP与UDP的差异

TCP与UDP流程对比 

TCP编程流程 

服务器端流程:

  1. 创建套接字(socket):使用socket()函数创建一个套接字,指定使用的协议族(如IPv4或IPv6)和socket类型(如流式socket)。
  2. 绑定套接字(bind):使用bind()函数将套接字与服务器的网络信息(如IP地址和端口号)进行绑定。
  3. 监听套接字(listen):使用listen()函数将套接字设置为监听状态,准备接收客户端的连接请求。
  4. 接受连接(accept):使用accept()函数阻塞等待客户端的连接请求,并返回一个新的套接字用于与该客户端进行通信。
  5. 进行通信(recv/send):使用recv()send()函数与客户端进行数据的接收和发送。
  6. 关闭套接字(close):通信完成后,使用close()函数关闭套接字,释放资源。

客户端流程:

  1. 创建套接字(socket):与服务器端相同,使用socket()函数创建一个套接字。
  2. 连接服务器(connect):使用connect()函数向服务器发起连接请求,指定服务器的IP地址和端口号。
  3. 进行通信(send/recv):连接建立后,使用send()recv()函数与服务器进行数据的发送和接收。
  4. 关闭套接字(close):通信完成后,使用close()函数关闭套接字,释放资源。

 二、TCP编程-socket

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);功能:创建一个套接字,返回一个文件描述符
参数:domain:通信域,协议族AF_UNIX 本地通信AF_INET ipv4网络协议AF_INET6 ipv6网络协议AF_PACKET 底层接口type:套接字的类型SOCK_STREAM 流式套接字(tcp)SOCK_DGRAM 数据报套接字(udp)SOCK_RAW 原始套接字(用于链路层)protocol:附加协议,如果不需要,则设置为0返回值:成功:文件描述符失败:‐1

 案例

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{//通过socket函数创建一个TCP套接字int sockfd;if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("fail to socket");exit(1);}printf("sockfd = %d\n", sockfd);return 0;
}

这段代码演示了如何使用C语言创建一个TCP套接字。在代码中,首先通过socket()函数创建了一个套接字,指定了协议族为AF_INET(IPv4),套接字类型为SOCK_STREAM(TCP)。如果创建失败,则会输出错误信息并退出程序。如果创建成功,则会输出套接字的文件描述符。最后,程序返回0表示正常退出。

 执行结果

 三、TCP客户端-connect、send、recv

3.1 connect函数

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:给服务器发送客户端的连接请求
参数:sockfd:文件描述符,socket函数的返回值addr:要连接的服务器的网络信息结构体(需要自己设置)addrlen:add的长度
返回值:成功:0失败:-1

注意:

  1. connect建立连接之后不会产生新的套接字
  2. 连接成功后才可以开始传输TCP数据
  3. 头文件:#include 

3.2 send函数

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);功能:发送数据
参数:sockfd:文件描述符客户端:socket函数的返回值
服务器:accept函数的返回值buf:发送的数据len:buf的长度flags:标志位0 阻塞MSG_DONTWAIT 非阻塞返回值:成功:发送的字节数失败:-1

注意不能用TCP协议发送0长度的数据包

3.3 recv函数

#include <sys/types.h>#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:接收数据
参数:sockfd:文件描述符
客户端:socket函数的返回值
服务器:accept函数的返回值buf:保存接收到的数据len:buf的长度flags:标志位0 阻塞MSG_DONTWAIT 非阻塞
返回值:成功:接收的字节数失败:-1
如果发送端关闭文件描述符或者关闭进程,则recv函数会返回0

3.4 客户端code

使用windows下的网络调试助手作为服务器

客户端的程序 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>#define N 128int main(int argc, char const *argv[])
{if(argc < 3){fprintf(stderr, "Usage: %s [ip] [port]\n", argv[0]);exit(1);}//第一步:创建套接字int sockfd;if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("fail to socket");exit(1);}//printf("sockfd = %d\n", sockfd);//第二步:发送客户端连接请求struct sockaddr_in serveraddr;socklen_t addrlen = sizeof(serveraddr);serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = inet_addr(argv[1]);serveraddr.sin_port = htons(atoi(argv[2]));if(connect(sockfd, (struct sockaddr *)&serveraddr, addrlen) == -1){perror("fail to connect");exit(1);}//第三步:进行通信//发送数据char buf[N] = "";fgets(buf, N, stdin);buf[strlen(buf) - 1] = '\0';if(send(sockfd, buf, N, 0) == -1){perror("fail to send");exit(1);}//接收数据char text[N] = "";if(recv(sockfd, text, N, 0) == -1){perror("fail to recv");exit(1);}printf("from server: %s\n", text);//第四步:关闭套接字文件描述符close(sockfd);return 0;
}

这段代码是一个简单的TCP客户端程序。它接收两个命令行参数:服务器的IP地址和端口号。然后,程序会执行以下步骤:

  1. 创建一个TCP套接字。
  2. 使用connect()函数向服务器发送连接请求。
  3. 从标准输入读取一行数据,并将其发送给服务器。
  4. 接收服务器返回的数据,并将其打印到标准输出。
  5. 关闭套接字文件描述符。

 执行结果

 

四、TCP服务器-bind、listen、accept 

4.1 做为TCP服务器需要具备的条件

1、具备一个可以确知的地址

2、让操作系统知道是一个服务器,而不是客户端

3、等待连接的到来 对于面向连接的TCP协议来说,连接的建立才真正意味着数据通信的开始

4.2 bind函数

#include <sys/types.h>#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:将套接字与网络信息结构体绑定
参数:sockfd:文件描述符,socket的返回值addr:网络信息结构体通用结构体(一般不用)struct sockaddr网络信息结构体 sockaddr_in
#include <netinet/in.h>
struct sockaddr_in
addrlen:addr的长度
返回值:成功:0失败:-1

 简单写个例子

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>int main() {// 创建一个流式套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("socket");return -1;}// 初始化网络信息结构体struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8080); // 绑定到8080端口addr.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定到任意IP地址// 将套接字与网络信息结构体绑定socklen_t addrlen = sizeof(addr);if (bind(sockfd, (struct sockaddr *)&addr, addrlen) == -1) {perror("bind");return -1;}printf("Bind successful\n");// 关闭套接字close(sockfd);return 0;
}

 在这个实例中,我们首先使用socket()函数

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞等待客户端的连接请求
参数:sockfd:文件描述符,socket函数的返回值addr:接收到的客户端的信息结构体(自动填充,定义变量即可)addrlen:addr的长度
返回值:成功:新的文件描述符(只要有客户端连接,就会产生新的文件描述符,这个新的文件描述符专门与指定的客户端进行通信的)失败:-1

创建了一个流式套接字,然后初始化了一个sockaddr_in结构体,将套接字绑定到8080端口和任意IP地址。最后,我们使用bind()函数将套接字与网络信息结构体绑定,如果绑定成功,则会输出"Bind successful"。

 4.3 listen函数

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
功能:将套接字设置为被动监听状态,这样做之后就可以接收到连接请求
参数:sockfd:文件描述符,socket函数返回值backlog:允许通信连接的主机个数,一般设置为5、10
返回值:成功:0失败:-1

4.4 accept函数

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞等待客户端的连接请求
参数:sockfd:文件描述符,socket函数的返回值addr:接收到的客户端的信息结构体(自动填充,定义变量即可)addrlen:addr的长度
返回值:成功:新的文件描述符(只要有客户端连接,就会产生新的文件描述符,这个新的文件描述符专门与指定的客户端进行通信的)失败:-1

 4.5 TCP服务器例子

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>#define N 128int main(int argc, char const *argv[])
{if(argc < 3){fprintf(stderr, "Usage: %s [ip] [port]\n", argv[0]);exit(1);}//第一步:创建套接字int sockfd;if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("fail to socket");exit(1);}//第二步:将套接字与服务器网络信息结构体绑定struct sockaddr_in serveraddr;socklen_t addrlen = sizeof(serveraddr);serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = inet_addr(argv[1]);serveraddr.sin_port = htons(atoi(argv[2]));if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) == -1){perror("fail to bind");exit(1);}//第三步:将套接字设置为被动监听状态if(listen(sockfd, 10) == -1){perror("fail to listen");exit(1);}//第四步:阻塞等待客户端的链接请求int acceptfd;struct sockaddr_in clientaddr;if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) == -1){perror("fail to accept");exit(1);}//打印连接的客户端的信息printf("ip:%s, port:%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));//第五步:进行通信//tcp服务器与客户端通信时,需要使用accept函数的返回值char buf[N] = "";if(recv(acceptfd, buf, N, 0) == -1){perror("fail to recv");}printf("from client: %s\n", buf);strcat(buf, " *_*");if(send(acceptfd, buf, N, 0) == -1){perror("fail to send");exit(1);}//关闭套接字文件描述符close(acceptfd);close(sockfd);return 0;
}

 

  1. 创建一个TCP套接字。
  2. 将套接字与服务器的IP地址和端口号绑定。
  3. 将套接字设置为被动监听状态,等待客户端的连接请求。
  4. 阻塞等待客户端的连接请求,并接受连接。
  5. 打印连接的客户端的IP地址和端口号。
  6. 接收客户端发送的数据,并将其打印出来。
  7. 向客户端发送数据。
  8. 关闭与客户端的连接,并关闭套接字。

 执行结果

4.6  close关闭套接字

  1. 使用close函数即可关闭套接字 关闭一个代表已连接套接字将导致另一端接收到一个0长度的数据包
  2. 做服务器时 1>关闭监听套接字将导致服务器无法接收新的连接,但不会影响已经建立的连接 2>关闭accept返回的已连接套接字将导致它所代表的连接被关闭,但不会影响服务器 的监听
  3. 做客户端时 关闭连接就是关闭连接,不意味着其他

 

相关文章:

TCP(TCP客户端、服务器如何通信)

一、TCP介绍 TCP的特点&#xff1a; 面向连接的协议&#xff1a;TCP是一种可靠的、面向连接的协议&#xff0c;在通信之前需要建立连接&#xff0c;以确保数据的可靠传输。这意味着在传输数据之前&#xff0c;发送方和接收方之间需要建立一条可靠的连接通道。流式协议&#x…...

pdf 文件版面分析--PyMuPDF (python 文档解析提取)

1.介绍 PyMuPDF 和Fitz 是用于Python中处理PDF文件的相关模块。Fitz是P有MuPDF的字模块。提供一个简化和封装版本的P有MuPDF功能。 关系&#xff1a; PyMuPDF&#xff1a; 提供广泛的功能&#xff0c;用于操作PDF文档&#xff0c; 包括方便的高级函数与底层操作Fitz &#x…...

sql update 多表关联 inner join

当您需要更新一个表或者多个表中的数据&#xff0c;而多个表又存在关联时&#xff0c;可以使用 INNER JOIN 子句将多个表关联起来&#xff0c;并使用 SET更新。 格式如下&#xff1a; UPDATE table1 INNER JOIN table2 ON table1.column1 table2.column1 SET table1.column2…...

【OceanBase诊断调优】—— 租户资源统计项及其查询方法

本文主要介绍 OceanBase 数据库中租户资源统计项及其查询方法。 适用版本 OceanBase 数据库 V4.1.x、V4.2.x 版本。 CPU 资源统计项 逻辑 CPU 使用率&#xff08;线程处理请求的时间占比&#xff09;。 通过虚拟表 __all_virtual_sysstat 在 SYS 系统租户下&#xff0c;查看…...

【一键录音,轻松转换:用Python打造个性化音频记录工具】

在数字化时代,音频记录已成为日常学习、工作和娱乐不可或缺的一部分。想象一下,只需简单按下几个键,即可随时随地捕捉灵感,记录会议要点,或是珍藏孩子的童言稚语。本文将引领您步入Python编程的奇妙世界,展示如何借助几个强大的库,构建一个既简单又实用的音频录制及转换…...

Java类与对象(一)

类的定义与使用 在Java中使用关键字class定义一个类&#xff0c;格式如下&#xff1a; class 类名{// 成员变量/字段/属性//成员方法/行为 }Java中类和c语言中的结构体有点类似&#xff0c; 在Java中类名一般采用大驼峰&#xff08;每个首字母大写&#xff09;的形式&#xf…...

python中的装饰器,例子说明

在Python中&#xff0c;嵌套装饰器是指在一个函数上应用多个装饰器。每个装饰器都可以为函数添加一些特定的功能。以下是一个稍微复杂一些的例子&#xff0c;我们将创建一个记录日志和验证权限的嵌套装饰器。 ### 例子&#xff1a;记录日志和权限验证的嵌套装饰器 假设我们正…...

Leetcode经典题目之用队列实现栈

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 目录 1、题目展示2、题目分析3、完整代码演示4、结语 1、题目展示 前面我们了解过如何实现队列…...

DBSCAN聚类算法

目录 背景DBSCAN算法DBSCAN算法原理DBSCAN算法基本步骤DBSCAN算法调优DBSCAN算法优缺点参考文献 背景 如果有车队在某一片区域经常规律性作业&#xff0c;现在要让你来绘制这一片的路网&#xff0c;你会选择让一辆车从头到尾把所有路网跑一遍还是基于历史轨迹点通过技术手段构…...

【tauri】安装

https://blog.csdn.net/freewebsys/article/details/136092092 1 安装nodejs curl -sL https://deb.nodesource.com/setup_18.x -o nodesource_setup.sh sudo bash nodesource_setup.sh sudo apt install nodejs # 查看版本 node -v2 安装webkit2 sudo apt update sudo apt i…...

(Java)心得:LeetCode——19.删除链表的倒数第 N 个节点

一、原题 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[]示例 3&…...

树莓派安装opencv

安装opencv 上述步骤完成后&#xff0c;输入以下代码(基于python3) sudo apt-get install python3-opencv -y不行的话&#xff0c;试试换源&#xff0c;然后 sudo apt-get update成功&#xff01; 测试opencv是否安装成功 输入 python3 然后再输入 import cv2 没有报错就…...

bert 的MLM框架任务-梯度累积

参考&#xff1a;BEHRT/task/MLM.ipynb at ca0163faf5ec09e5b31b064b20085f6608c2b6d1 deepmedicine/BEHRT GitHub class BertConfig(Bert.modeling.BertConfig):def __init__(self, config):super(BertConfig, self).__init__(vocab_size_or_config_json_fileconfig.get(vo…...

Nginx配置/.well-known/pki-validation/

当你需要在Nginx上配置.well-known/pki-validation/时&#xff0c;这通常是为了支持SSL证书的自动续订或其他验证目的。以下是配置步骤&#xff1a; 创建目录结构&#xff1a; 在你的网站根目录下创建一个名为.well-known的目录&#xff08;SSL证书申请之如何创建/.well-known/…...

iOS LQG开发框架(持续更新)

基本规则 开发便利性为前提&#xff0c;妥协性能可维护性为前提可读性MVC各部分职责一定要清晰&#xff0c;controll类里面功能尽量抽离成helper&#xff0c;功能一定要清晰&#xff0c;这个非常重要&#xff0c;对代码可读性提升非常高方法内部尽量使用局部变量&#xff0c;最…...

Python 自动化脚本系列:第3集

21. 使用 cryptography 自动化文件加密 Python 的 cryptography 库提供了一种安全的方式&#xff0c;使用对称加密算法对文件进行加密和解密。你可以自动化加密和解密文件的过程来保护敏感数据。 示例&#xff1a;文件加密和解密 假设你想使用对称加密算法加密一个文件&…...

Matlab-粒子群优化算法实现

文章目录 一、粒子群优化算法二、相关概念和流程图三、例题实现结果 一、粒子群优化算法 粒子群优化算法起源于鸟类觅食的经验&#xff0c;也就是一群鸟在一个大空间内随机寻找食物&#xff0c;目标是找到食物最多的地方。以下是几个条件: (1) 所有的鸟都会共享自己的位置以及…...

python 新特性

文章目录 formatted字符串字面值formatted字符串支持 字符串新方法变量类型标注二进制表示中数字为1的数量统计字典的三个方法新增mapping属性函数zip()新增strict参数dataclass字典合并match 语法 formatted字符串字面值 formatted字符串是带有’f’字符前缀的字符串&#xf…...

十一、Redis持久化-RDB、AOF

Redis提供了两种持久化数据的方式。一种是RDB快照&#xff0c;另一种是AOF日志。RDB快照是一次全量备份&#xff0c;AOF日志是连续的增量备份。RDB快照是以二进制的方式存放Redis中的数据&#xff0c;在存储上比较紧凑&#xff1b;AOF日志记录的是对内存数据修改的指令文本记录…...

Oracle闪回数据库【Oracle闪回技术】(二)

理解Oracle闪回级别【Oracle闪回技术】(一)-CSDN博客 Oracle默认是不开启闪回数据库的。如果开启闪回数据库的前提条件是,开启Oracle归档模式并启用闪回恢复区。 因为闪回日志文件存放在闪回恢复区中,如果在RAC环境下,必须将闪回恢复区存储在集群文件或者ASM文件中。 一…...

简单负载均衡

题目描述 某工程师为了解决服务器负载过高的问题&#xff0c;决定使用多个服务器来分担请求消息。 现给定 k 台服务器&#xff08;编号从 1 到 k&#xff09;&#xff0c;以及一批请求消息的信息&#xff0c;格式为到达时刻 负载大小&#xff0c;消息说明&#xff1a; 每个时刻…...

Portforge:一款功能强大的轻量级端口混淆工具

关于Portforge Portforge是一款功能强大的轻量级端口混淆工具&#xff0c;该工具使用Crystal语言开发&#xff0c;可以帮助广大研究人员防止网络映射&#xff0c;这样一来&#xff0c;他人就无法查看到你设备正在运行&#xff08;或没有运行&#xff09;的服务和程序了。简而言…...

1.8. 离散时间鞅-无界停时定理与随机游走

无界停时定理与随机游走 无界停时定理与随机游走1. 无界停时定理1.1. 一致可积1.2. 非一致可积2. 应用于随机游动-鞅方法2.1. 随机游走构造的鞅2.2. 对称简单随机游走无界停时定理与随机游走 1. 无界停时定理 本节给出一致可积下鞅的无界停时定理,说明一致可积下鞅的停止过程…...

Google Pixel4手机刷机+Root+逆向环境详细教程

Google Pixel4手机刷机Root逆向环境配置详细教程 刷机工具下载 Windows10、Google Pixel4手机当前安卓10系统、adb工具、要刷的谷歌原生的Android11最新刷机包、安装google usb驱动、美版临时twrp-3.6.0_11-0-flame.img和美版永久twrp-installer-3.6.0_11-0-flame.zip、Magis…...

IT项目管理-小题计算【太原理工大学】

1.合同总价问题 问承包商的利润是&#xff1f; 实际利润目标利润&#xff08;目标成本-实际成本&#xff09;*卖方分担比例 解&#xff1a;10 000&#xff08;100 000 - 90 000&#xff09;* 0.2 12 000&#xff08;元&#xff09; 实际成本有时也写作最终成本&#xff0c;问承…...

ARP欺骗使局域网内设备断网

一、实验准备 kali系统&#xff1a;可使用虚拟机软件模拟 kali虚拟机镜像链接&#xff1a;https://www.kali.org/get-kali/#kali-virtual-machines 注意虚拟机网络适配器采用桥接模式 局域网内存在指定断网的设备 二、实验步骤 打开kali系统命令行&#xff1a;ctrlaltt可快…...

Android动画(四):PathMeasure实现路径动画

文章概览 1 PathMeasure概述2 实现路径加载动画3 实现箭头加载动画4 实现操作成功动画 本系列将介绍以下内容&#xff1a; Android动画 1 PathMeasure概述 PathMeasure是一个单独的类&#xff0c;其全部源码如下&#xff08;请详细研读注释&#xff09;&#xff1a; package…...

HTTP 连接详解

概述 世界上几乎所有的 HTTP 通信都是由 TCP/IP 承载的&#xff0c;客户端可以打开一条TCP/IP连接&#xff0c;连接到任何地方的服务器。一旦连接建立&#xff0c;客户端和服务器之间交换的报文就永远不会丢失、受损或失序 TCP&#xff08;Transmission Control Protocol&…...

练习题(2024/5/12)

1二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输出: 4…...

Day50代码随想录动态规划part12:309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费

Day50 动态规划part12 股票问题 309.最佳买卖股票时机含冷冻期 leetcode题目链接&#xff1a;309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; 题意&#xff1a;给定一个整数数组&#xff0c;其中第 i 个元素代表了第 i 天的股票价格 。设计一个算…...