V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
paulw54jrn
V2EX  ›  问与答

一个关于 TCP 粘包的问题.

  •  
  •   paulw54jrn · 2014-04-14 00:41:47 +08:00 · 2864 次点击
    这是一个创建于 3875 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需要用c实现一个简单的C/S程序.
    Client端因为需要在收到SIGIO信号之后在Handler里面接受字节流,Server端使用Select()轮询可用的FileDescriptor. 每次发送的字节数固定不变(recv的大小预先知道).
    两边公用的接收代码如下:


    现在的问题是程序经常跑飞,在客户端经常会发现接收的字节数为-1;
    Bytes received -> -1 , need more bytes 4170

    在服务器端有时可以成功,有时会失败,收到字节数为0:
    Bytes received -> 0 , need more bytes 4170;

    问题是是,如果客户端收到了SIGIO信号后,不是能够说明TCP管道中有数据可以被读,那为什么初选recv == -1 的情况? 同理,服务器端使用Select(),不是同样说明管道中有数据,为何读取的时候字节数为0?

    Google过关于TCP Message Fragment的问题,建议是用循环把包拼起来,直到大小正确为止.但是目前用这个办法效果不太好. 是我哪里写的不对?
    4 条回复    1970-01-01 08:00:00 +08:00
    alexapollo
        1
    alexapollo  
       2014-04-14 00:49:13 +08:00
    man recv
    这是一个基础问题。
    xdeng
        2
    xdeng  
       2014-04-14 01:11:03 +08:00 via iPhone
    -1断开?
    paulw54jrn
        3
    paulw54jrn  
    OP
       2014-04-14 08:23:35 +08:00
    @alexapollo
    man page 我看过,我也明白这是一个基础问题. 也许正是太基础了,网上的描述都比较简单. 按照网上的建议,试了用几种不同的方式来把数据拼接在一起,但是都会有问题. 我觉得是我对Signal和Select的理解不够,所以想看看大家的意见.

    除了吐槽之外,还请'请尽量让自己的回复能够对别人有帮助'.
    vietor
        4
    vietor  
       2014-04-14 09:39:18 +08:00
    SIGPIPE应该disable掉,同时对于粘包使用一定的拼接缓冲区是无法避免的。此外,使用SIGIO来作为事件通知也太古老了,难道是mac环境?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1000 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 19:53 · PVG 03:53 · LAX 11:53 · JFK 14:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.