吃透传输层:UDP 无连接、TCP 可靠传输、套接字函数、粘包问题详解

1.UDP协议

传输层:

UDP协议:用户数据报协议(User Datagrams Protocal)

UDP特点:

  1. 无连接;
  2. 面向数据报;
  3. 尽最大努力交付协议,不安全不可靠(丢包、乱序);
  4. 机制简单,实时性好,效率高。
    比如:直播、游戏画面

1 . 网络通信模型

B/S :Browser/Server : 浏览器/服务器

  1. 通用客户端
  2. 数据资源基本都保存在服务端
  3. 只需要开发服务

C/S :Client / Server :客户端/服务端

  • 专用客户端
  • 客户端和服务端都可以保存资源
  • 客户端和服务端都需要开发

2. UDP通信

  • socket

int socket(int domain, int type, int protocol);

功能:创建通信的套接字

参数:

domain:使用的协议族

AF_INET : IPv4 (网络层)

AF_INET6 :IPv6

type :传输层的协议类型

SOCK_STREAM : TCP

SOCK_DGRAM : UDP

protocol :0 默认方式

返回值:

成功:文件描述符(套接字)

失败:-1

套接字:应用层网络通信的端口,文件描述符

  • sendto
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
    const struct sockaddr *dest_addr, socklen_t addrlen);

功能:发送udp数据报文

参数:

sockfd:套接字

buf : 要发送的数据首地址

len:发送的数据字节数

flags : 0 按照默认方式发送

dest_addr:服务端的地址信息(IP + PORT)

addrlen :地址信息的长度

返回值:

成功:发送的字节数

失败:-1

struct sockaddr_in {

sa_family_t sin_family; /* address family: AF_INET /
in_port_t sin_port; /
port in network byte order /
struct in_addr sin_addr; /
internet address */

};

/* Internet address. /
struct in_addr {
uint32_t s_addr; /
address in network byte order

*/

};

0x1122

0x2211

网络字节序:大端 (高地址存低字节位,低地址存高字节位)

主机字节序:小端 (高地址存高字节位,低地址存低字节位)

  • bind
    int bind(int sockfd, const struct sockaddr *addr,
    socklen_t addrlen);

功能:绑定当前套接字和IP地址及端口号

参数:

sockfd:套接字

addr:要绑定的地址信息指针

addrlen:地址信息的长度

返回值:

成功:0

失败:-1

  • recvfrom
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
    struct sockaddr *src_addr, socklen_t *addrlen);

功能:接收UDP数据报文

参数:

sockfd:套接字*

buf:存储网络接收到的数据

len :期望接收到的字节数

flags:0 默认方式接收

src_addr:保存发送发地址信息的指针

addrlen:地址长度的指针

返回值:

成功:实际接收到的字节数

失败:-1

0 :当对方发送0字节数据包

注意:

in_addr_t inet_addr(const char *cp);

功能:将点分十进制的字符串IP地址转换成32位的二进制IP地址形式

参数:

cp:字符串IP地址

返回值:

整形ip地址

tons :2字节数据,主机字节序转网络字节序

htonl :4字节数据,主机字节序转网络字节序

ntohs :2字节数据,网络字节序转主机字节序

ntohl :4字节数据,网络字节序转主机字节序

inet_add

char *inet_ntoa(struct in_addr in);

功能:将结构体类型的IP地址转换成字符串的IP地址

2.网络抓包工具

wireshark :网络抓包工具,可以抓取经过网卡的网络数据,从而分析网络问题和网络数据。(sudo apt-get install wireshark)

Linux下安装wireshark:

抓包流程:

  1. 启动wireshark : sudo wireshark
  2. 选择抓取的网卡:any
  3. 选择抓取数据包的过滤条件并触发:udp.port == 50000
  4. 进行网络通信

3. TCP协议

传输层

TCP: 传输控制协议(流式套接字)

1 . TCP特点

  1. 有连接;
  2. 面向字节流;
  3. 安全可靠的传输协议
    三次握手、四次挥手、应答机制、超时重传机制...等
  4. 机制复杂,实时性和效率没有UDP高
    HTTPS、MQTT、FTP

2 . TCP的三次握手和四次挥手机制

三次握手:TCP建立连接时,通过三次握手,来确保通信双方都已经准备就绪。

三次握手由客户端发起。

  • connect

    int connect(int sockfd, const struct sockaddr *addr,

    socklen_t addrlen);

    功能:请求建立连接

    参数:

    sockfd:套接字

    addr :服务端的地址

    addrlen:地址长度

    返回值:

    成功:0

    失败:-1

  • listen

    int listen(int sockfd, int backlog);

    功能:监听客户端的三次握手

    参数:

    sockfd:监听套接字

    backlog:最多允许监听的客户端的个数

    返回值:

    成功:0

    失败:-1

  • accept

    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

    功能:接收完成三次握手的客户端,并返回一个通讯套接字

    参数:

    sockfd:监听套接字

    addr:保存接入的客户端的地址信息的指针

    addrlen:地址信息长度的指针

    返回值:

    成功:通讯套接字

    失败:-1

  • recv

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

    功能:接收网络数据

    参数:

    sockfd:通讯套接字

    buf:存放接收到的数据的空间首地址

    len:期待接收到的字节数

    flags: 0 默认方式

    返回值:

    成功:返回实际收到的字节数

    失败:-1

    0:发送断开连接

3. TCP报文头部

标志位:

TCP报文头部数据位:

SYN:请求建立连接标志位

ACK :效应报文标志位

PSH:携带数据的报文标志位

FIN:请求断开连接标志位

URG:紧急数据标志位

RST:重置标志位

4. TCP机制

三次握手机制:

四次挥手机制:

应答机制:TCP为发送的数据进行编号,发送数据时,报文头部的序列号是这包数据的第一个数据的编号;将

来接收方需要给这包数据发送ACK,ACK报文中确认号是收到的最后一个字节编号+1;

超时重传机制:TCP每发送一包数据后都要等待应答,如果超时时间之内没有收到应答,则重新发送这包数

据。

滑动窗口机制:缓冲区,保存已发送并收到应答的数据、已发送未收到应答的数据、未发送但在对方处理范围

内的数据。

延迟应答机制:TCP可以发送多组数据,发送的同时等待应答。

流量控制机制:TCP会根据发送端的数据处理和接收能力调整自己的发送速率,根据ACK中窗口值的大小进行动

态调整流量。

捎带应答机制:ACK可以和应用层发送的数据一起发出,表示对上包数据的响应。

5. TCP粘包

粘包:发送端发送速度太快,接收端处理速度比较慢,导致数据在缓冲区缓存,应用层读出数据

时,多包数据发生了粘连。

如何解决:

  1. 收发指定大小数据(收发结构体)
    注意:跨平台发送时平台的位数。
    struct data
    {
    xxx;
    long num;
    };
    send(sockfd, &data, sizeof(struct data), 0);
    recv(sockfd, &data, sizeof(struct data), 0);
  2. 给发送的数据明显的分割符,应用层根据分隔符解析
    hello\n
    world\n
    hello\nworld\n
  3. 以自定义方式定义发送的数据帧格式,接收方严格按照协议方式解析
    帧头 数据长度 消息类型 校验 帧尾
    5A 0101 1010
    A5
    7E
    E7
    EB90
    消息类型 :区分数据包的数据类型
    校验:8位和校验:checksum
    16位和校验
    CRC校验
相关推荐
SendTomo1 小时前
SendTomo 与 send.wang 全景对比评测与实战指南
网络·网络协议·tcp/ip·webrtc·p2p
Shadow(⊙o⊙)1 小时前
Linux网络——IP协议 子网 路由 IP的分片字段
服务器·网络·tcp/ip
单片机仿真设计2 小时前
基于 51 单片机老旧电梯层门防夹人装置优化设计(Proteus 仿真)
单片机·嵌入式硬件·proteus
wuyk5554 小时前
104.C 语言字节对齐:从底层原理到工程实践的完整指南
c语言·开发语言·stm32·单片机·嵌入式硬件
4A广告文案11 小时前
名创优品在成都开了家“乐园”,顺便造了个新IP
网络·网络协议·tcp/ip
新晨单片机设计12 小时前
S006A-基于STM32单片机温湿度检测系统【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus
逐步前行14 小时前
ESP32-S3-分区表(Partition Table)
单片机
TechWayfarer14 小时前
Cloudflare 9·15新政倒计时:用IP风险画像识别AI爬虫,防止误伤Googlebot
网络·人工智能·爬虫·python·tcp/ip·网络安全
星河单片机14 小时前
STM32驱动HS‑S37A水位传感器+OLED完整实验讲解
stm32·单片机·嵌入式硬件