嵌入式第四十一篇——网络编程——udp和tcp

一、udp(用户数据报协议)

1、udp特性

(1)无连接

通信双方不需要预先建立连接,发送方直接向网络中发送数据报,接收方也无需提前准备接收。省去了 TCP 的三次握手、四次挥手流程,通信效率更高。

(2)不可靠

不保证数据报的顺序送达:发送的数据包可能乱序到达接收端。

不保证不丢失:数据包在传输过程中丢失后,UDP 不会重传。

不进行拥塞控制:即使网络拥堵,UDP 也会持续以固定速率发送数据。

(3)开销小、传输快

UDP 头部只有 8 字节(远小于 TCP 的 20 字节头部),协议本身的处理开销极低,适合对实时性要求高的场景。

2、数据报特性

(1)数据与数据之间有边界; 数据报是以独立数据包为单位传输的,每个数据包都是一个完整的 "数据块",接收方可以准确区分不同的数据包边界。

(2)发送和接收的次数要对应; 因为数据报有明确边界,发送多少次,理论上就需要接收多少次才能获取全部数据。

**(3)发送无阻塞(默认),发送太快会丢包;**数据报的发送接口默认不阻塞(或阻塞阈值很高),当发送速率超过底层链路的传输能力时,超出的数据包会被直接丢弃。

(4)读取默认阻塞; 数据报的接收接口(如 recvfrom)默认是阻塞模式 :如果缓冲区中没有待接收的数据包,程序会暂停在 recvfrom 调用处,直到有新的数据包到达或超时。

3、服务端与客户端

服务端(Server) :提供资源、功能或服务的一方,核心是 "被动响应请求"。

客户端(Client) :发起服务请求的一方,核心是 "主动发起请求"。

函数调用步骤

server:socket() =>bind()=>recvfrom()===>close()

client:socket()--->sendto() ----->close()

udp客户端与服务端函数调用关系:

复制代码
1、int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符
参数:domain 地址族,PF_INET == AF_INET ==>互联网程序
PF_UNIX == AF_UNIX ==>单机程序
type 套接字类型:
SOCK_STREAM 流式套接字 ===》TCP
SOCK_DGRAM 用户数据报套接字===>UDP
SOCK_RAW 原始套接字 ===》IP
protocol 协议 ==》0 表示自动适应应用层协议。
返回值:成功 返回申请的套接字id;
失败 -1;

2、int bind(int sockfd, struct sockaddr *my_addr,
socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关
的文件描述符文件与参数2 指定的接口地址关联,
用于从该接口接受数据。
sockfd, 需要被绑定 ip 和端口号的套接字
my_addr ipv4 对应的地址结构体,man 7 ip
struct _sockaddr_in ///网络地址结构
{
u_short sin_family; ////地址族
u_short sin_port; ///地址端口
struct in_addr sin_addr; ///地址IP
};
socklen_t addrlen: 参数2 的长度。
返回值:成功 0
失败 -1;
发送接收函数:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
功能:用于UDP协议中向对方发送数据。
参数:sockfd 本地的套接字id
buff 本地的数据存储,一般是要发送的数据。
len 要发送的数据长度
flags 要发送数据方式,0 表示阻塞发送。
dest_addr: 必选,表示要发送到的目标主机信息结构体。
addrlen :目标地址长度。
返回值:成功 发送的数据长度
失败 -1;
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
功能:用于UDP协议中获取对方发送的数据。
参数:sockfd 本地的套接字id
buff 要存储数据的内存区,一般是数组或者动态内存。
len 要获取的数据长度,一般是buff的大小。
flags 获取方式,0 阻塞
src_addr 可选,表示对方的地址信息结构体,
如果为NULL,表示不关心对方地址。
addrlen 对方地址信息结构体大小。
如果对方地址是NULL,则该值也为NULL。
返回值:成功 接收到的数据长度
失败 -1

二、TCP (传输控制协议)

1、特征

1.有链接 三次握手(服务器和客户端之间,一旦连接建立。链路就会一直保持。 直到其中一方表示要断开)

  1. 可靠传输

3.流式套接字,数据没有边界。 连续的,有顺序的。

4.全双工,双缓存区

5.发送次数和接收次数不需要对应。

6.有写阻塞 64K

  1. 如果对方端口连接,另外一方可以感知 4次挥手

  2. 实时性弱

9.网络资源消耗大

可靠传输依靠:1.应答 ack num,2.超时重传

2.监听套接字与通信套接字的关系

3、黏包问题

tcp在通信过程中,数据之间没有边界,接收方不能还原数据。发送方可以发送多次,接收发 ,一次性接送,导致数据不能正常解析的现象。

4、建立链接

三次握手,四次挥手

5、tcp 函数调用顺序

6、tcp的相关函数

复制代码
1、int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符
参数:domain 地址族,PF_INET == AF_INET ==>互联网程序
PF_UNIX == AF_UNIX ==>单机程序
type 套接字类型:
SOCK_STREAM 流式套接字 ===》TCP
SOCK_DGRAM 用户数据报套接字===>UDP
SOCK_RAW 原始套接字 ===》IP
protocol 协议 ==》0 表示自动适应应用层协议。
返回值:成功 返回申请的套接字id
失败 -1;

2、int bind(int sockfd, struct sockaddr *my_addr,
socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关
的文件描述符文件与参数2 指定的接口地址关联,
用于从该接口接受数据。

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

4、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;

5.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;

6. 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;
客户端 自动连接服务器。
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:该函数固定有客户端使用,表示从当前主机向目标
主机发起链接请求。
参数:sockfd 本地socket创建的套接子id
addr 远程目标主机的地址信息。
addrlen: 参数2的长度。
返回值:成功 0
失败 -1;
相关推荐
水星灭绝2 小时前
测试http下载
网络·网络协议·http
行业探路者2 小时前
录音转二维码与视频二维码生成器的使用指南
人工智能·学习·音视频·二维码·产品介绍
走在路上的菜鸟2 小时前
Android学Dart学习笔记第二十八节 Isolates
android·笔记·学习·flutter
开***能2 小时前
精准控能耗,协议零阻碍!EtherCAT转 Profinet网关技术赋能
服务器·网络·人工智能
Darkershadow2 小时前
蓝牙学习之亮度调节
学习·蓝牙·ble
秋深枫叶红2 小时前
嵌入式第四十三篇——数据库
linux·数据库·学习·oracle
q行2 小时前
java学习日志--内部类
java·学习·内部类
好奇龙猫2 小时前
【AI学习-comfyUI学习-第二十九节-instantID+IP加载器预工作流-各个部分学习】
人工智能·学习
QT 小鲜肉2 小时前
【Linux命令大全】001.文件管理之split命令(实操篇)
linux·运维·服务器·网络·笔记