You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C Socket快速批量发送消息时客户端合并显示问题求助

TCP Socket消息合并显示的原因解析

问题现象

服务器通过循环快速向客户端发送多条消息时,客户端将所有消息合并为一个字符串显示;在每次write后添加sleep(1),客户端则能正常分条显示各消息。

无sleep的服务器代码

int nombreDeJoueurs = joueurs + robots;
int taille;
for(i = 1; i<= nombreDeJoueurs; i++){
    sprintf(saisie,"Le joueur %d a %d têtes de boeufs", i, vie[i]);
    for (j = 1; j <= joueurs; j++){
        taille = write(pollfds[j].fd,saisie,strlen(saisie));
    }
}

对应客户端输出

Le joueur 1 a 1 têtes de boeufsLe joueur 2 a 0 têtes de boeufsLe joueur 3 a 0 têtes de boeufsLe joueur 4 a 0 têtes de boeufs


带sleep的服务器代码

int nombreDeJoueurs = joueurs + robots;
int taille;
for(i = 1; i<= nombreDeJoueurs; i++){
    sprintf(saisie,"Le joueur %d a %d têtes de boeufs", i, vie[i]);
    for (j = 1; j <= joueurs; j++){
        taille = write(pollfds[j].fd,saisie,strlen(saisie));
        sleep(1);
    }
}

对应客户端输出

Le joueur 1 a 1 têtes de boeufs
Le joueur 2 a 0 têtes de boeufs
Le joueur 3 a 0 têtes de boeufs
Le joueur 4 a 0 têtes de boeufs

原因解释

这是TCP协议的字节流特性引发的「粘包」现象,核心逻辑如下:

  • TCP是面向字节流的传输协议,它不会为应用层的消息自动添加边界标记。操作系统为了提升网络传输效率,会通过Nagle算法将多次小的write操作合并成一个较大的数据包发送——当服务器快速连续调用write时,这些小数据块会被操作系统的发送缓冲区合并,一次性传输给客户端。
  • 客户端的read操作仅从接收缓冲区读取字节,无法区分这些字节对应多少个应用层消息,因此会把收到的所有字节一次性取出,表现为消息合并显示。
  • 添加sleep(1)后,两次write的间隔足够长,操作系统会判定这是独立的发送操作,不会合并缓冲区数据,客户端就能分条接收并显示每条消息。

内容的提问来源于stack exchange,提问作者Momo LaTorpie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:20:57