TCP粘包和抓包

在 TCP 套接字中,发送和接收缓冲区用于暂存数据,以确保数据的可靠传输。具体来说,TCP 的 socket 收发缓冲区的主要特点和概念如下:

1. 发送缓冲区(Send Buffer)

定义: 发送缓冲区用于存储待发送的数据。应用程序将数据写入发送缓冲区,TCP 协议会将这些数据逐渐发送到网络中。

大小 : 发送缓冲区的大小可以通过套接字选项进行配置,默认大小通常由操作系统决定。可以使用 setsockopt() 函数来修改送的缓冲区大小,例如:

int size = 1048576; // 1MB setsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));

2. 接收缓冲区(Receive Buffer)

定义: 接收缓冲区用于存储接收到的网络数据,通常由 TCP 协议管理。数据从网络中接收后,首先会存入接收缓冲区,应用程序随后从缓冲区中读取数据。

大小 : 跟发送缓冲区一样,接收缓冲区的大小也可以通过 setsockopt() 调整。例如:

int size = 1048576; // 1MB setsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));

3. 缓冲区管理

TCP 是面向连接的协议,使用流控、拥塞控制等机制来管理数据传输。当发送缓冲区满时,发送操作会被阻塞,直到有数据被确认接收,腾出空间;同样,接收缓冲区满时,recv() 调用将阻塞,直到缓冲区有可读数据。

4. 缓冲区溢出

如果接收缓冲区的大小不够以存放所有传入的数据,丢失的数据将被丢弃。因此,合理设置缓冲区的大小对提升 TCP 性能是重要的。

5. 查看缓冲区大小(仅在 Linux 上)

使用 getsockopt() 函数可以查看当前缓冲区的大小。例如:

int size; socklen_t optlen = sizeof(size); getsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, &size, &optlen); printf("Send buffer size: %d\n", size); getsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, &size, &optlen); printf("Receive buffer size: %d\n", size);

6. 影响因素

(1)网络带宽: 高带宽网络可能需要更大的发送和接收缓冲区。

(2)延迟和延迟带宽积: 高延迟的连接通常需要更大的缓冲区,以防止网络延迟导致的传输效率降低。

粘包:

粘包的原因:

  1. TCP流的特性 :TCP 是一种面向字节流的协议,无论发送方发送多少次数据,接收方可能在一次 recv 调用中接收到多个数据包,或者一个数据包被拆分为多个部分。

  2. 数据发送速率:发送方的连接速率快于接收方处理速率,造成多个数据在同一时间到达。

  3. 数据包大小差异:当小的数据包被频繁发送时,TCP 可能会将它们合并在一起以减少网络协议开销。

  4. 网络拥塞:网络拥塞可能会导致数据在发送过程中的堆积,从而导致粘包。

解决方案:

  1. 固定长度协议:每个数据包有固定的字节长度,接收方只需按此长度接收数据。

  2. 分隔符协议 :在每个数据包后添加特定的分隔符(如 \nEOF 等),接收方通过检测分隔符来分割数据包。

  3. 消息头:在每个数据包前加上一个头部,头部包含消息体的长度信息。接收方先读取头部,知道完整消息的长度后,再读取相应字节的数据。

    例如,可以设计如下数据格式:

    [length][data]

    其中 length 为数据长度(通常为 4 字节),data 为实际数据。

  4. 使用高层协议:使用已有的高层协议(如 HTTP、WebSocket 等),这些协议内置了解决粘包问题的机制

127.0.0.1 是一个特殊的IP地址,称为回环地址,通常用于网络测试和本地通信。它代表本地计算机或设备本身。使用这个地址,您可以在没有网络连接的情况下测试网络应用程序,因为所有通过该地址发送的数据都返回给同一设备。

二、recv和send

1. send 函数

send 函数用于在已连接的 socket 上发送数据。它的基本原型如下(C语言):

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

  • 参数说明:

    • sockfd: 套接字描述符,标识已连接的 socket。
    • buf: 指向包含要发送数据的缓冲区的指针。
    • len: 要发送的数据的长度(字节数)。
    • flags: 发送操作的标志,通常可以为0。
  • 返回值:

    • 成功时返回实际发送的字节数;失败时返回 -1,并设置 errno。

2. recv 函数

recv 函数用于从连接的 socket 接收数据。它的基本原型如下(C语言):

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

  • 参数说明:

    • sockfd: 套接字描述符,标识已连接的 socket。
    • buf: 指向一个缓冲区,接收到的数据将存储在其中。
    • len: 缓冲区的大小(字节数)。
    • flags: 接收操作的标志,通常可以为0。
  • 返回值:

    • 成功时返回实际接收的字节数;返回值为0表示对方关闭了连接;失败时返回 -1,并设置 errno。

三、常用网络调试工具

ifconfig//查看主机上,网卡网络信息

ping//测试 两台主机之间是否连通

telnet//远程登录工具

ssh//硬件(开发板)

netstat// 查看当前主机上,活动的网络进程的相关的状态信息

arp

抓包

四、HTTP

1.http (超文本传输协议)

2.URL统一资源定位符

相关推荐
2401_8574396942 分钟前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php
远游客07132 小时前
centos stream 8下载安装遇到的坑
linux·服务器·centos
fantasy_arch4 小时前
CPU性能优化-磁盘空间和解析时间
网络·性能优化
LIKEYYLL4 小时前
GNU Octave:特性、使用案例、工具箱、环境与界面
服务器·gnu
云云3215 小时前
搭建云手机平台的技术要求?
服务器·线性代数·安全·智能手机·矩阵
云云3215 小时前
云手机有哪些用途?云手机选择推荐
服务器·线性代数·安全·智能手机·矩阵
CircleMouse5 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
是Dream呀6 小时前
Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络
网络·python·神经网络
木子Linux6 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
kaixin_learn_qt_ing6 小时前
了解RPC
网络·网络协议·rpc