网络(3)TCP通信

这几天学习了TCP通信。它和UDP通信是网络通信的重点。

TCP是面向连接的协议,正式收发数据之前,要通过三次握手建立连接,通信结束使用四次挥手断开连接。

三次握手

  1. 客户端(主动发起连接)发送SYN报文
  2. 服务器返回 ACK+SYN
  3. 客户端回复ACK,连接建立完成。

四次挥手

用来结束TCP连接,保证数据完整传输。

如果双方没有待传输数据,四次挥手也会简化成三次挥手。

主动关闭端发送FIN

被动关闭端回复ACK;如果数据全部发送完毕,会继续发送ACK+FIN

被动关闭端再发送FIN

主动关闭端回复ACK

TCP依靠序号、确认序号保证数据完整可靠传输。

序号:代表当前数据包起始字节编号

确认序号:接收方告诉发送方,下一次希望收到的字节编号

还有滑动窗口做流量控制,拥塞控制应对网络拥堵,掉线检测机制维护连接状态。

TCP粘包问题

TCP是流式协议,没有消息边界。连续发送多份数据,接收端有可能把多条数据包粘在一起收到。

常见解决办法:

  1. 发送之间增加延时
  2. 设置消息边界,比如用\r\n做分隔符
  3. 使用定长发送

TCP报文头部

TCP头部固定20字节。里面有多个标志位:

SYN:请求建立连接

ACK:确认应答

FIN:结束通信

RST:重置连接

PSH:推送数据

URG:紧急数据

ACK标志置1的时候,32位确认序号才会生效。

TCP socket核心函数

客户端函数

  1. socket() 创建套接字

    int tcpsocket = socket(AF_INET, SOCK_STREAM, 0);

    AF_INET代表IPv4,SOCK_STREAM代表TCP流套接字。

  2. connect():客户端主动发起连接

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

    sockfd:socket文件描述符

    addr:目标服务器地址

    addrlen:地址结构体长度

    返回0成功,‑1失败。

  3. send():向套接字发送数据

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

    buf:发送缓冲区首地址;len:发送长度;flags一般填0

    返回:成功返回发送字节数;失败返回‑1。

  4. recv():从套接字接收数据

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

    buf:接收缓冲区;len:最大接收字节;flags默认0

    返回:成功返回收到字节;失败‑1;返回0代表对方关闭连接。

服务器端函数

  1. listen():开启监听,等待客户端连接请求

    int listen(int sockfd, int backlog);

    backlog:内核中未处理连接请求队列的最大个数。成功返回0,失败‑1。

  2. accept():取出监听队列第一个客户端连接

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

    sockfd:监听socket

    addr:保存客户端地址信息

    addrlen:传入地址结构体大小,调用后输出实际地址长度

    返回值:返回新的文件描述符,后续和客户端通信就使用这个新fd。

TCP与UDP对比

TCP UDP

连接 面向连接 无连接

可靠性 可靠安全 不可靠

资源开销 开销大 开销小

实现逻辑 复杂 简单

UDP不用建立连接,速度快,但是会丢包,不保证顺序。

小结

  1. TCP要先三次握手建连接,结束四次挥手;存在粘包,要自己处理消息边界。
  2. 客户端:socket → connect → send/recv
  3. 服务器:socket → listen → accept → send/recv
  4. recv返回0代表对端断开,这点写代码一定要留意。
相关推荐
虎头金猫2 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
wuyk5552 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
XUEYUAN52122 天前
ASN 自治系统号风控:平台如何通过 IP 所属自治域批量识别代理流量
python·网络协议·http·网络安全·socks5
QYRdata2 天前
年均增速24.2%!机器人数据湖未来六年增长动能强劲
网络·机器人·服务发现
CHENKONG_CK2 天前
破解制鞋打磨痛点:RFID赋能去毛刺工序自动化升级
网络·单片机·嵌入式硬件·网络协议·tcp/ip
chshang19922 天前
工业路由器是什么?浅谈5G工业网络中的IR602
网络·物联网·5g·智能路由器
萧瑟余晖2 天前
Netty 核心组件与 Reactor 模型详解
网络·架构
ITxiaobing20232 天前
IP 定位服务选型指南:从准确率到工程落地的技术考察
linux·服务器·网络
wuyk5552 天前
【Socket 进阶之路】第 9 章 Linux 网络服务量产稳定性优化|心跳保活、TIME_WAIT、SO_LINGER、内存池、断线重连、完整异常防护框架
linux·服务器·开发语言·网络·物联网
z落落2 天前
C#UDP+串口服务端+UDP 客户端(含 CRC16 校验)
网络·网络协议·udp