> 技术文档 > Linux网络编程-tcp

Linux网络编程-tcp


tcp、udp对比:

UDP

1. 特点

  • 无连接:无需建立连接即可发送数据
  • 不可靠:不保证数据顺序或完整性。
  • 低延迟:适合实时性要求高的场景。

2. 应用场景

  • 视频/音频流传输(如直播)。
  • DNS 查询、在线游戏。

TCP

1. 特点

  • 面向连接:通过三次握手建立连接。
  • 可靠传输:通过序列号SYN、ACK 确认和重传机制保证数据完整性。
  • 流量控制:滑动窗口机制避免网络拥塞。

一、三次握手和四次挥手和其余机制

🌟 1. 三次握手的第二个阶段为什么是 ACK+SYN?
        核心目标:同步序列号 + 确认能力。
                TCP 是全双工协议,双方需独立确认发送和接收能力。
                SYN 用于交换初始序列号(ISN),ACK 用于确认收到 SYN。
        合并原因:
                减少网络开销(从 4 次握手优化为 3 次)。
                服务器收到 SYN 后必须立即确认(ACK),同时需同步自己的序列号(SYN)。
🌟 2. 四次挥手的确认和结束为什么要分开发送?
        核心目标:非对称关闭 + 数据传输可能性。
                一方可能仍有数据需要发送(如 HTTP 响应剩余部分)。
                FIN 表示“无数据发送”,ACK 表示“已收到 FIN”。
        分开发送原因:
                被动关闭方可能无法立即停止发送数据。
                合并 FIN+ACK 会导致被动关闭方无法完成剩余数据传输。
🌟 3. 关键差异总结

方面 三次握手 四次挥手

目标

双向同步序列号 + 确认能力 非对称关闭连接 SYN/FIN 的角色 同步初始序列号(必须立即确认) 请求关闭连接(可能延迟发送) ACK 的角色 确认 SYN(必须立即发送) 确认 FIN(可能延迟发送) 合并的必要性 合并为 SYN+ACK 减少开销

无法合并,因 FIN 和 ACK 发送时机不同

其余机制:

1.应答机制:为每个数据增加序列发,发送数据时,第一个数据的序号作为报文中的序号。接收方收到相关数据,会回应ACK报文,报文中的确认号是接收方下次希望接收到的数据的起始序号

2.超时重传机制:TCP发送数据后会在一定的时间内等待ACK,假设在指定时间ACK未收到,则视为此数据包丢失,

二、 tcp相关接口

1. send 函数
        ssize_t send(int sockfd, const void *buf, size_t len, int flags);
        功能:发送数据。
        参数:
                sockfd:套接字文件描述符。
                buf:数据缓冲区首地址。
                len:数据长度。
                flags:默认设为 0。
        返回值:
                成功:发送的字节数。
                失败:-1。
2. recv 函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
        功能:从 TCP 套接字接收数据。
        参数:
                sockfd:套接字文件描述符。
                buf:保存接收数据的缓冲区首地址。
                len:期待接收的字节数。
                flags:默认设为 0。
        返回值:
                成功:实际接收的字节数。
                发送端关闭时:返回 0。
                失败:-1。
3. listen 函数
int listen(int sockfd, int backlog);
        功能:监听三次握手请求。
        参数:
                sockfd:套接字文件描述符。
                backlog:等待处理的三次握手请求的最大数量。
        返回值:
                成功:0。
                失败:-1。
4. accept 函数
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
        功能:处理三次握手队列中的第一个请求,创建新套接字。
        参数:
                sockfd:套接字文件描述符。
                addr:保存客户端 IP 地址的缓冲区首地址。
                addrlen:IP 地址长度。
        返回值:
                成功:新套接字文件描述符。
                失败:-1。

三、TCP粘包问题

1.TCP在接受数据时,多包数据粘在一起

2.原因:

        (1)TCP发送数据时,会根据缓冲区数据的情况进行重新组包

        (2)TCP接收方,没有及时读走缓冲区数据,导致缓冲区大量数据缓存。

3.如何解决

        (1)发指定大小字节

将要发数据,封装在结构体里

struct data

{

        int id;

        float tmp;

        xxx

}; 

缺点:发送端与接收端体系不同,32位与64位对齐方式的不同造成数据丢失;所有要在指定的相同平台使用,注意结构体对齐问题。

        (2)发送具有指定分隔符的数据

        hello world\\n

        miss you\\n

        (3)封装自定义数据帧

        AA len0C  0001 0112 1314 1504 XXXX XXXXBB

        校验:8位和校验

                  16位和校验

四、网络抓包

抓取通过设备网卡的数据

wireshark:网络抓包工具

        1.分析和追踪网络问题

        2.查看网络协议栈

安装:sudo apt-get install wireshark

1.sudo wireshark

2.选择通信设备的网卡==》any

3.选择抓取的过滤条件

4.开始抓取

5.进行一次通信

五、TCP报文头

标志位:紧急指针标志,为I时表示紧急指针有效,该报文应该优先传送,
1. URG:
确认应答标志
2 ACK:
表示发送数据,提示接收端从TCP接收缓冲区中读走数据,为接收后续数据腾出空间
3.PSH:
4. RST:重置连接标志
表示请求建立一个连接5.SYN:
fmish标志,表示释放连接6.FN