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

学习嵌入式的第三十二天——网络编程——TCP - 实践

服务端/客户端模型

c/s:c专用 标准协议/自定义协议 资源大部分在客户端,服务器只进行关键交互数据的收发,功能比b/s复杂

b(browser)/s:c通用 利用http协议 资源由服务器发给客户端 受http限制,功能不复杂

p2p:下载类软件和直播类软件 客户端从服务器下载数据的同时也会给后面的客户端上传信息

TCP(传输控制协议)

特点

1.有链接:在发送消息前,会先打通一条链路,在一次会话中,链路不会改变,

客户端和服务端可以检测对方是否关闭,当一端关闭时,另一端也会关闭

2.可靠传输:应答机制,自动重传

3.流式套接字,数据连续且有顺序,材料间无边界,会有粘包问题

解决:1.设置边界,2.固定大小,3.自定义协议

4.全双工通信:有两个缓冲区,每个大小64K,缓冲区满会阻塞,收发互不影响

三次握手,四次挥手

有连接的通信过程,需要三次握手建立链接。就是TCP

两台主机之间的通信链路建立必须如下过程:

主机1 -----syn-----》主机2
主机1 《---ack syn--- 主机2
主机1 ----ack -----》主机2

通过抓包来验证三次握手:
1、 tcpdump -n -i lo tcp port 9999 ===>S S. .
2、 wireshark 规则: tcp.port == 9999 ===>syn syn ack ack

问题:
三次握手分别是在服务器和客户端的那个函数上完成。

结论:
客户端函数:connect()
服务器函数:listen()

四次挥手

主机1 --- F A ---》主机2
主机1 《---A ----- 主机2 主机1 不在发送消息,但是有可能接受消息

主机1 《---F A --- 主机2
主机1 ----A ----》主机2 主机1 2 全部完毕

TCP编程步骤

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

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;

接受函数:/发送函数:


read()/write () ///通用记录读写,可以操作套接字。
recv(,0) /send(,0) ///TCP 常用套机字读写
recvfrom()/sendto() ///UDP 常用套接字读写

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;

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:该函数固定有客户端使用,表示从当前主机向目标
主机发起链接请求。
参数:sockfd 本地socket创建的套接子id
addr 远程目标主机的地址信息。
addrlen: 参数2的长度。
返回值:成功 0
失败 -1;

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;

TCP与UDP的区别

TCP

1.有链接:在发送消息前,会先打通一条链路,在一次会话中,链路不会改变(三次握手,四次挥手),客户端和服务端可以检测对方是否关闭,当一端关闭时,另一端可以知道

2.可靠传输:应答机制,自动重传

3.流式套接字,数据连续且有顺序,内容间无边界,会有粘包难题

应对:1.设置边界,2.固定大小,3.自定义协议

4.全双工通信:有两个缓冲区,每个大小64K,缓冲区满会阻塞,收发互不影响

UDP

否关闭,需要手动关闭,我写过一个基于UDP的两端聊天效果,由于另一端无法自动检测,因此我在一端关闭前向另一端发送一个结束标志,来通知另一端。就是1.无连接:客户端与服务端无法检测对方

2.不可靠,内容会有丢包风险

3.数据报 发送和接收次数必须对应,数据之间有边界

4.无拥塞控制 不会管网络是否拥挤,会继续发送,大大增加丢包率

5.可以组播,广播(仅限UDP)

6.首部开销小

http://www.jsqmd.com/news/2370/

相关文章:

  • EasyDSS “进度条预览”黑科技,如何重塑视频点播的交互体验?
  • 2025 年在线 Excel 协作工具:纯前端架构引领协作范式革新
  • AI重塑招聘:从筛简历到做决策,HR如何借技术提效35%?
  • 大屏适配不同分辨率
  • 直播点播之外,EasyDSS如何开辟“实时协作”第三极?它的会议功能,远比你想象的强大
  • 详细介绍:【HTML】 第一章:HTML 基础
  • 抖音视频关键词批量下载工具分享|分享痛点|
  • HarmonyOS动态照片,简易环境助力高效开发
  • 二叉树专题
  • IT项目管理主要做什么?-ManageEngine卓豪
  • 9.22学习笔记
  • 实用指南:详解RabbitMQ高级特性之延迟插件的安装和使用
  • Django 视图层
  • 第二部分:VTK核心类详解(第38章 vtkPointData点数据类) - 教程
  • Kettle: pentaho-server-9.4登录问题
  • Win11/Win10/Office 永久激活
  • springboot~获取原注解的方法findMergedAnnotation使用场景
  • Catalan数(卡特兰数)
  • IvorySQL文档共建计划第一期!提 PR,提 Issue,赢取 Beats 耳机、机械键盘、书籍等多重好礼!
  • ubuntu22.04 安装xrdp
  • 题解:P14058 【MX-X21-T3】[IAMOI R5] 两个人的演唱会
  • CSP-J 2025 初赛试题解析(第一部分:阅读程序题(一)(16-21)) - 指南
  • 深入解析Wallarm安全边缘:API边缘的即时防护技术
  • 使用ai来搭建测试用例1
  • 面试八股文之——JVM与并发编程/多线程 - 教程
  • 总线的概念以及分类
  • A Great Beginning
  • 邮件系统的未来趋势:技术革新与智能化的未来
  • python-uv入门使用 - 教程
  • docker volume使用