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统一资源定位符

相关推荐
BingoGo13 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack13 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
Sinclair2 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
JaguarJack2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
Rockbean3 天前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek
茶杯梦轩3 天前
CompletableFuture 在 项目实战 中 创建异步任务 的核心优势及使用场景
服务器·后端·面试
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel