TCP day39

六:C/S和B/S端

C/S:Client, server
B/S:Browser server

1.cs 专用客户端 bs 通用客户端
2.协议不同
Cs 标准协议,自定义协议
Bs http 超文本传输
3.cs 功能复杂 bs 功能弱
4.bs 资源都在ser,有ser发送到cli
cs 大部分资源都在cli

七:UDP和TCP特性

UDP:

  1. 无连接
    不需要维护繁杂网络状态。网络开销小。通信双方通信过程,无法知道对方进程关闭。如果需要告知,需要发信息通知。
  2. 不可靠,
    传输数据的过程中,会有丢包。但是实时性好。适用直播 视频传输,音频传输。
    3.很容易实现一对多 。
    4.可以组播,广播

TCP:

1.有链接,一次会话中,链接一直保持。如果一个断开,另外一方可以感知
2.可靠 。靠机制保障。应答超时重传

八:流式套接字

流式套接字 是一种tcp socket 队列
1.有顺序,连续
2.发送和接收的次数不需要对应。
3.send 发送快,写阻塞

流式套接字 是一种tcp socket 队列
1.有顺序,连续
2.发送和接收的次数不需要对应。
3.send 发送快,写阻塞

流式套接字 是一种tcp socket 队列
1.有顺序,连续
2.发送和接收的次数不需要对应。
3.send 发送快,写阻塞

  1. 数据之间没有边界

数据没有边界会导致数据的黏包
接收收到数据后,无法正常解析

解决方法1.协商边界
2.固定大小
3.自定义协议

//3.
eg:		AA       03      1 2 3        crc     BB开始    长度     数据      校验      结束//都是自己定义的形式

九:TCP服务器和客户端函数流程

服务器
socket(); 打开网络设备 获得文件描述符(套接字) listfd 监听套接字,作用,就是三次握手
bind();// 给套接字设定ip(确定主机)+port(对应到进程pid)
listen(); 使监听套集字进入监听状态(可以被三次握手的状态)
accept();// 服务器和客户端进入三次握手阶段,并建立连接。并获得通信套接字(服务器和客户端后续进行通信,用的套接字)
recv() ;;//阻塞接收客户端的数据。 0 ==ret 代表对方断开连接。-1 ,代表错误。 >0 实际接收到的字节数。
send();//发送的数据。 发送过程中有可能阻塞。发送的快,把对方的缓冲区填满就阻塞。
close().当收到对方的断开请求(0 == recv())。就断开与客户端的通信。
客户端
socket(); 打开网络设备 获得文件描述符(套接字) ,通信套接字
connect();客户端主动连接服务器 。触发三次握手。
send() ;//发送的数据。 发送过程中有可能阻塞。发送的快,把对方的缓冲区填满就阻塞。
recv();//阻塞接收客户端的数据。 0 ==ret 代表对方断开连接。-1 ,代表错误。 >0 实际接收到的字节数。
close(); 当客户端请求服务完成后,主动关闭套接字。触发四次挥手。

9.1:三次握手/四次挥手
三次握手
c->syn(请求连接), c_num(起始发送数据的编号)   -> s 
s->syn,ACK(应答)S_num(起始发送数据的编号)->c 
c -> ACK  ->s 四次挥手
c->FIN(断开连接)->ACK-> s 
s->ACK (应答上次fin的请求)->c 
s-> FIN(断开连接) +ACK (应答上次fin的请求)->c 
c -> ACK(s-> FIN(断开连接))->s

十:服务器端

10.1:listen
int listen(int sockfd, int backlog);

功能:在参数1所在的套接字id上监听等待链接。
参数:sockfd 套接字id
backlog 允许链接的个数。
返回值:成功 0, 失败 -1;

10.2:accept
int accept(int sockfd, struct sockaddr *addr,socklen_t *addrlen);// 这里有阻塞

功能:从已经监听到的队列中取出有效的客户端链接并接入到当前程序。
参数:sockfd 套接字id
addr 如果该值为NULL ,表示不论客户端是谁都接入。
如果要获取客户端信息,则事先定义变量并传入变量地址,函数执行完毕将会将客户端信息存储到该变量中。
addrlen: 参数2的长度,如果参数2为NULL,则该值也为NULL;
如果参数不是NULL,&len;
一定要写成len = sizeof(struct sockaddr);

返回值:成功 返回一个用于通信的新套接字id;从该代码之后所有通信都基于该id, 失败 -1;

10.3:recv
ssize_t recv(int sockfd, void *buf, size_t len,int flags);

功能:从指定的sockfd套接字中以flags方式获取长度
为len字节的数据到指定的buff内存中。
参数:sockfd
如果服务器则是accept的返回值的新fd
如果客户端则是socket的返回值旧fd
buff 用来存储数据的本地内存,一般是数组或者
动态内存。
len 要获取的数据长度
flags 获取数据的方式,0 表示阻塞接受。

返回值:成功 表示接受的数据长度,一般小于等于len
失败 -1;

十一:客户端

11.1:connect
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

功能:该函数固定有客户端使用,表示从当前主机向目标
主机发起链接请求。
参数:sockfd 本地socket创建的套接子id
addr 远程目标主机的地址信息。
addrlen: 参数2的长度。
返回值:成功 0, 失败 -1;
ps:套接字不是单独给网络用的,可以用别名强转

11.2:send
int send(int sockfd, const void *msg, size_t len, int flags);

功能:从msg所在的内存中获取长度为len的数据以flags 方式写入到sockfd对应的套接字中。

参数:sockfd:如果是服务器则是accept的返回值新fd
如果是客户端则是sockfd的返回值旧fd

msg: 要发送的消息
len: 要发送的消息长度
flags :消息的发送方式。

返回值:成功 发送的字符长度, 失败 -1;

十二:实例

//ser
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr*(SA);
int main(int argc, char** argv)
{//监听套接字 功能检测是否有客户端 连连接服务器int listfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == listfd){perror("socket");return 1;}struct sockaddr_in ser, cli;bzero(&ser, sizeof(ser));bzero(&cli, sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本机地址  外部客户端可以连接到服务器ser.sin_addr.s_addr = INADDR_ANY;//任何人都可以连接,相当于ser.sin_addr.s_addr = 0int ret = bind(listfd, (SA)&ser, sizeof(ser));if (-1 == ret){perror("bind");return 1;}// 同一时刻可以服务器建立连接的排队数listen(listfd, 3);socklen_t len = sizeof(cli);//和客户端建立连接,并获得通信套接字,这个套接字就代表客户端int conn = accept(listfd, (SA)&cli, &len);if (-1 == conn){perror("accept");return 1;}while (1){char buf[512] = {0};int rec_ret= recv(conn, buf, sizeof(buf), 0);if(rec_ret<=0){break;}printf("from cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf, "%s %s", buf, ctime(&tm));int sd_ret = send(conn, buf, strlen(buf), 0);if(sd_ret<=0){break;}}close(listfd);close(conn);// system("pause");return 0;
}
//cli
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr *(SA);int main(int argc, char **argv)
{int conn = socket(AF_INET, SOCK_STREAM, 0);if (-1 == conn){perror("socket");return 1;}struct sockaddr_in ser;bzero(&ser, sizeof(ser));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本机地址  外部客户端可以连接到服务器ser.sin_addr.s_addr = inet_addr("192.168.116.130");int ret = connect(conn, (SA)&ser, sizeof(ser));if (-1 == ret){perror("connect");return 1;}while (1){char buf[512] = "hello,this tcp test";int sd_ret = send(conn, buf, strlen(buf), 0);if(sd_ret<=0){break;}bzero(buf, sizeof(buf));int ret_rec = recv(conn, buf, sizeof(buf), 0);if(ret_rec<=0){break;}printf("from  ser:%s\n",buf);sleep(1);}close(conn);// system("pause");return 0;
}

十三:tcp_cp_struct

//ser
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr*(SA);
typedef struct
{char name[256];int size;char buf[4096];int buf_size;} MSG;
int main(int argc, char** argv)
{//监听套接字 功能检测是否有客户端 连连接服务器int listfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == listfd){perror("socket");return 1;}struct sockaddr_in ser, cli;bzero(&ser, sizeof(ser));bzero(&cli, sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本机地址  外部客户端可以连接到服务器ser.sin_addr.s_addr = INADDR_ANY;int ret = bind(listfd, (SA)&ser, sizeof(ser));if (-1 == ret){perror("bind");return 1;}// 同一时刻可以服务器建立连接的排队数listen(listfd, 3);socklen_t len = sizeof(cli);//和客户端建立连接,并获得通信套接字,这个套接字就代表客户端int conn = accept(listfd, (SA)&cli, &len);if (-1 == conn){perror("accept");return 1;}MSG msg;bzero(&msg, sizeof(msg));int flag = 0;int fd = -1;int total_size = 0;int currnet_size = 0;while (1){int re_ret = recv(conn, &msg, sizeof(msg), 0);if (re_ret <= 0){break;}if (0 == flag){flag = 1;fd = open(msg.name, O_WRONLY | O_CREAT | O_TRUNC, 0666);if (-1 == fd){perror("open");return 1;}total_size = msg.size;}if (msg.buf_size <= 0){break;}write(fd, msg.buf, msg.buf_size);currnet_size += msg.buf_size;printf("size:%d\n", currnet_size);if (currnet_size == total_size){  //文件传输结束break;}bzero(&msg, sizeof(msg));strcpy(msg.buf, "go on");send(conn, &msg, sizeof(msg), 0);}close(listfd);close(conn);close(fd);// system("pause");return 0;
}
//cli
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h> /* See NOTES */
#include <time.h>
#include <unistd.h>
typedef struct sockaddr *(SA);
typedef struct
{char name[256];int size;char buf[4096];int buf_size;} MSG;
int main(int argc, char **argv)
{int conn = socket(AF_INET, SOCK_STREAM, 0);if (-1 == conn){perror("socket");return 1;}struct sockaddr_in ser;bzero(&ser, sizeof(ser));ser.sin_family = AF_INET;ser.sin_port = htons(50000);// 代表本机地址  外部客户端可以连接到服务器ser.sin_addr.s_addr = inet_addr("192.168.116.130");int ret = connect(conn, (SA)&ser, sizeof(ser));if (-1 == ret){perror("connect");return 1;}MSG msg;strcpy(msg.name, "2.png");struct stat st;ret = stat("/home/linux/1.png", &st);if (-1 == ret){perror("stat");return 1;}msg.size = st.st_size;int fd = open("/home/linux/1.png", O_RDONLY);if (-1 == fd){perror("open");return 1;}while (1){msg.buf_size = read(fd, msg.buf, sizeof(msg.buf));send(conn, &msg, sizeof(msg), 0);  // 固定大小的方式if (msg.buf_size <= 0){break;}bzero(&msg, sizeof(msg));recv(conn, &msg, sizeof(msg), 0);}close(conn);// system("pause");return 0;
}

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

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

相关文章

6 种无线传输照片从安卓到 Mac 的方法

将大量照片从安卓设备传输到电脑上&#xff0c;不仅可以备份照片&#xff0c;还能释放设备存储空间。虽然使用 USB 数据线可以在 Windows 电脑上轻松完成传输&#xff0c;但将安卓手机连接到 Mac 并非如此简单。因此&#xff0c;许多用户更倾向于无线传输照片从安卓到 Mac。您可…

在vscode 使用 remote-ssh

vscode安装插件Remote-SSH,直接安装即可 安装完毕之后 在左下角有这个图标 点击之后选择连接到主机然后选择添加新链接之后输入用户名和主机地址 非默认端口使用 -p 端口号之后选择第一个即可如果使用的是密码,直接连接,然后输入密码即可如果使用的密钥,则修改.ssh\config文件中…

RabbitMQ03——面试题

目录 一、mq的作用和使用场景 二、mq的优点 2.1架构设计优势 2.2功能特性优势 2.3性能与可靠性优势 2.4生态系统优势 2.5对比优势 三、mq的缺点 3.1性能与扩展性限制 3.2功能局限性 3.3运维复杂度 3.4与其他消息队列的对比劣势 四、mq相关产品&#xff0c;每种产品…

应用层攻防启示录:HTTP/HTTPS攻击的精准拦截之道

一、七层攻击的复杂性 # CC攻击模拟工具&#xff08;Python实现&#xff09; import requests import threadingtarget_url "https://example.com/search?q"def cc_attack():while True:# 构造恶意搜索请求malicious_query "0" * 1000 # 长查询参数try…

.net 警告【代码 CS1998】此异步方法缺少 “await“ 运算符,将以同步方式运行。

【代码 CS1998】此异步方法缺少 “await” 运算符&#xff0c;将以同步方式运行。请考虑使用 “await” 运算符等待非阻止的 API 调用&#xff0c;或者使用 “await Task.Run(…)” 在后台线程上执行占用大量 CPU 的工作。在 VS 2022 中遇到的 CS1998 编译器警告&#xff0c;表…

【自动驾驶黑科技】基于Frenet坐标系的车道变换轨迹规划系统实现(附完整代码)

1. 代码结构概览该代码实现了一个车道变换轨迹规划系统&#xff0c;包含两个核心模块&#xff1a;道路建模&#xff08;EnhancedRoadModel&#xff09;&#xff1a;基于样条曲线构建道路模型。轨迹规划&#xff08;LaneChangePlanner&#xff09;&#xff1a;根据障碍物状态和道…

uni-calendar自定义签到打卡颜色

uni-calendar自定义签到打卡颜色&#xff0c;只需要将打卡的状态添加到动态类class中即可 效果&#xff1a;在uni-modules >>> components >>> uni-calendar >>> uni-calendar-item.vue文件中&#xff0c;根据info对应的文字或者符号添加不同的clas…

浙江大学PTA程序设计C语言基础编程练习题1-5

&#x1f30f;个人博客主页&#xff1a;意疏-CSDN博客 希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 阅读指南&#xff1a;开篇说明题目一、厘米换算英寸题目二、然后是几点题目三、 逆序…

catkin build的config设置指南[设置多种make模式或策略]

在本篇文章中&#xff0c;我们来尽可能详细地深入探讨 catkin config 的使用方法。这是掌握 catkin_tools 工作流的关键&#xff0c;能极大地提升你的开发效率和项目的规范性。 catkin config 的核心思想 首先&#xff0c;要理解它的核心思想&#xff1a;为你的 Catkin 工作空间…

Ubuntu挂载和取消挂载

在 Ubuntu 中&#xff0c;挂载&#xff08;Mount&#xff09;和取消挂载&#xff08;Unmount&#xff09;是管理存储设备&#xff08;如硬盘、U盘、ISO镜像等&#xff09;的常见操作。以下是详细指南&#xff1a;1. 挂载&#xff08;Mount&#xff09; 1.1 查看可用存储设备 ls…

Vue开发常用库(含npm安装命令)

Vue开发常用库&#xff08;含npm安装命令&#xff09; 核心生态系统&#xff1a;Vue Router - 官方路由管理器 npm install vue-router4 # Vue 3 npm install vue-router3 # Vue 2Pinia - 新一代状态管理库 npm install piniaVuex - 传统状态管理库 npm install vuexnext …

[硬件电路-39]:激光光路的光信号处理、模拟电路的电信号处理、数字电路的电信号处理、软件的信号处理,有哪些共通的操作、运算、变换?

激光光路、模拟电路、数字电路及软件中的信号处理在操作、运算和变换层面存在显著共性&#xff0c;这些共性体现了信号处理的核心逻辑在不同技术领域的通用性。以下是具体分析&#xff1a; 目录 一、共通操作&#xff1a;信号处理的基础动作 1、放大与衰减 2、滤波 3、调制…

Grails(Groovy)框架抛出NoHandlerFoundException而不是返回404 Not Found

本文记录在基于Spring(Boot)框架&#xff08;使用Java语言&#xff09;和Grails框架&#xff08;使用Groovy语言&#xff09;下&#xff0c;开发Controller接口&#xff0c;对不存在的URL请求&#xff0c;接口返回404 not found&#xff0c;而不是抛出NoHandlerFoundException异…

muduo中事件循环线程池的理解

事件循环线程池的理解前置知识reactor模型thread::start()方法的理解创建线程池子线程被唤醒的几种情况子线程被主线程唤醒新连接到来有消息需要发送时&#xff08;多reactor情况时&#xff09;关闭连接时子线程被唤醒执行任务在 上一篇中&#xff0c;我们讨论了关于简单的线程…

AI智能体“上下文工程”实践:来自 Manus 项目的经验总结

转载&#xff1a;https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus 在启动 Manus (manus.im/app) 项目之初&#xff0c;我的团队面临一个关键抉择&#xff1a;究竟是基于开源基础模型训练一个端到端的智能体模型&#xff0c;还是在前沿大…

day19 链表

定义链式存储的线性表头文件相关定义 typedef int datatype;//定义数据域类型 typedef struct Node {union{int len; //头结点数据域datatype data; //普通节点数据域};struct Node *next; //节点指针域 }Node,*Node_ptr;链表的函数 注意事项 1.创建节点时&#xff0c;需要初…

【第三节】Class与Style绑定

文章目录Class与Style绑定绑定HTML Class对象语法数组语法绑定内联样式对象语法数组语法自动添加前缀Class与Style绑定 数据绑定一个常见需求是操作元素的 class 列表和它的内联样式,因为它们都是属性&#xff0c;我们可以用 v-bind 处理它们:我们只需要计算出表达式最终的字符…

CMOS知识点 离子注入工艺

知识点8&#xff1a;离子注入是为了将掺杂剂&#xff08;如硼、磷等&#xff09;精确引入硅晶片的近表面区域&#xff0c;以改变其电学性质。工艺过程&#xff1a;电离与加速&#xff1a;掺杂剂原子在离子源中被电离&#xff08;带电&#xff09;&#xff0c;通过高压电场&…

从安装到上手:Ubuntu 22.04 玩转 Containerd 2.1.3 容器运行时

Containerd 是一款支持 OCI 规范的容器运行时&#xff0c;注重容器部署和生命周期管理的简单性、健壮性与可移植性&#xff0c;常被嵌入到 Docker 和 Kubernetes 等系统中。本文将详细介绍在 Ubuntu 22.04 服务器上通过二进制包手动安装 Containerd 的完整步骤&#xff0c;包括…

Hadoop与云原生集成:弹性扩缩容与OSS存储分离架构深度解析

Hadoop与云原生集成的必要性Hadoop在大数据领域的基石地位作为大数据处理领域的奠基性技术&#xff0c;Hadoop自2006年诞生以来已形成包含HDFS、YARN、MapReduce三大核心组件的完整生态体系。根据CSDN技术社区的分析报告&#xff0c;全球超过75%的《财富》500强企业仍在使用Had…