当前位置: 首页 > news >正文

libevent的粘包笔记

“粘包”现象是指 多个数据包的内容被合并在一起,一次性被接收端读取了,从而造成接收方难以区分包与包的边界。

简而言之:粘包 = 同时收到两个或多个包的内容了。


更详细解释:

粘包常出现在 TCP协议 中,原因是:

  • TCP 是面向字节流的协议,没有消息边界的概念;

  • 如果发送端连续发送多个小数据包,TCP 可能会将它们合并为一个较大的包发送出去;

  • 接收端读取时就会一次性读到多个包的内容,而不是一个一个独立的包。


举个例子:

假设发送端连续发送了两个数据包:

包1: Hello 包2: World

粘包时,接收端可能一次 recv() 就读到:

HelloWorld


对比一下“拆包”(另一个相关概念):

  • 拆包 是指一个数据包太大,被 TCP 拆成了若干段分别发送,接收端一次 recv() 可能只能读到其中一部分。


如何解决粘包问题?

通常要靠 应用层协议来定包的边界,常见方法有:

  1. 固定长度:每个包长度固定,比如每个包100字节。

  2. 分隔符:在每个包末尾加上特殊字符,如 \n|END| 等。

  3. 包头加长度字段:先发送一个表示包体长度的字段,然后再发送包体。

其它问题

除了粘包和拆包的基本理论知识,想进行一次完整的实战体验,还要了解所用网络库的接口机制和底层机制,比如本次我操作的是:libevent网络库在差分数据同步中的应用。

先看下发送端代码把:

int net_send_diff_data(S_CONNECT *conn, char *dest_file_name, FILE_METEDATA *p_meta,MASTER_CONFIG *p_local_pmaster_cfg, GQueue *tag_queue)
{int len = 0;uint32_t total_len = 0;int left_len = 0;int ret = ZX_SUCCESS;int njson_len = 0;char *str_json = NULL;cJSON *cjson = NULL;FILE *fp = NULL;char* buffer = malloc(MAX_READ_BUFFER);char *pkg = NULL;int16_t uextend;uint64_t diff_data_len = 0;int diff_tags = tag_queue->length;EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();TRUNK_INFO* ptrunk_info = malloc(sizeof(TRUNK_INFO) + MAX_READ_BUFFER);if (!ptrunk_info){ret = ZX_ERR_GENERAL;goto exit;}(void)p_local_pmaster_cfg;cjson = cJSON_CreateObject();if(cjson){cJSON_AddStringToObject(cjson, "file_name", dest_file_name);#ifdef _MSC_VERsprintf(buffer, "%I64u", p_meta->file_stat.st_size);#elsesprintf(buffer, "%lu", p_meta->file_stat.st_size);#endifcJSON_AddStringToObject(cjson, "file_size", buffer);sprintf(buffer, "%d", tag_queue->length + 1);cJSON_AddStringToObject(cjson, "diff_trunks_sum", buffer);sprintf(buffer, "%d", p_meta->file_stat.st_mode);cJSON_AddStringToObject(cjson, "file_mode", buffer);}else{log_error(__FILE__,__LINE__,"cJSON_CreateObject failed");ret = ZX_ERR_GENERAL;goto exit;}str_json = cJSON_Print(cjson);njson_len = strlen(str_json);cJSON_Delete(cjson);fp = zfopen(p_meta->file_name, "rb");if(!fp){log_error(__FILE__,__LINE__,"net_send_diff_data fopen %s failed ,ERR : %s",p_meta->file_name, strerror(errno));ret = ZX_ERR_FD_OPEN;goto exit;}pkg = malloc(sizeof(COMMON_PKG) + njson_len);uextend = -100 - njson_len;/* 发包头 */net_create_package((COMMON_PKG *)pkg, PKG_TYPE_ZCOPY_TO_ZCOPY_SYNC,PKG_TYPE_SYNC_SET_FILE_TRUNKS_DATA_REQ,IS_JSON,

相关文章:

  • Python编程6——面向对象编程1
  • Java基础 Day23
  • 宏的高级应用 ——一种 C 语言的元编程技巧(X-Macro)
  • ArgoDB表类型及常用命令
  • Cancer Cell|从临床病例到AI空间组学 | 空间生物标志物如何精准预测HER2阳性乳腺癌ADC疗效?
  • v1.05 支付宝 绑定时写Nand flash卡死问题
  • ⭐️⭐️⭐️ 免费的AI Clouder认证 ⭐️⭐️⭐️ 第四弹【课时1:课程概览】for「大模型Clouder认证:基于通义灵码实现高效AI编码」
  • 关于余数的定理
  • xcode 编译运行错误 Sandbox: rsync(29343) deny(1) file-write-create
  • Δ-Σ ADC的工作原理
  • 002 flutter基础 初始文件讲解(1)
  • C++链式调用与Builder模式
  • 28、请求处理-【源码分析】-请求映射原理
  • P1613 跑路
  • pcl::PointCloud2 的结构与sensor_msgs::msg::PointCloud2一样,pcl::PointCloud<T>
  • LLM 对齐新范式:深入解析 DPO (Direct Preference Optimization) 的原理与实践
  • RISC-V特权模式及切换
  • [Java恶补day9] 438.找到字符串中所有字母异位词
  • 202505系分论文《论信息系统开发方法及应用》
  • 决胜2025:企业级BI产品深度评测与选型指南
  • 吉林省长春市长春网站建设哪家好/优化大师
  • 做网站可以使用免费空间吗/seo和sem是什么
  • 涡阳网站建设/网页制作
  • 学校设计网站方案/商务网站建设
  • 好的兼职做调查网站/自动秒收录网
  • 建站的步骤/seo是什么公司