冰果

技术群:26678700     
交流QQ: 704839634
合作: 1) 可兼职远程办公开发; 2) 有一套Go+Python开发的行业短信云平台可合作;3)目前正在开发物联网、大数据平台。

recv行为描述错了

      上一篇说recv()问题,我描述错误了,很多网友一眼就发现了,而且指了出来,十分感谢。
      更难得的是第4位回复者,不但发现我的错误,而且能推测出我实现中是怎么做的,这种分析能力,一方面体现出你一定的实际开发经验,另一方面也体现了你对需求理解能力一定很不错。
      正如第4位回复者所说,为了能方便使用经典的同步-阻塞模式,一般会采用select()-recv()搭配调用,还会对recv()进行封装.
      ssize_t recv(int s, void *buf, size_t len, int flags);
      其行为是有数据就返回,返回实际收到长度: [1,  len], 或者正常关闭返回0, 或者出现错误返回-1.
      因为我们应用常常喜欢使用包头固定长度 + 包体变长模式来处理,我们是知道我们一定要多长才能正确得到一个协议包的,所以收满一个固定包头长度才能处理,得到包体长度值,再用这个长度去接收包体。
      因此做一个封装是常见现象:

bool Read(int sock, char * buffer, size_t len)
{
        int ret = 0;
        while( len > 0 ) {
                ret = recv( sock, buffer, len, 0 );
                if( 0 >= ret ) {
                        return false;
                }
                buffer += ret;
                len -= ret;
        }
        return true;
}
      这个其实也不完全是现实中的,现实中可能返回int, 可能里面有日志处理,可能直接有close()。
      总之,这么封装之后,你调用Read( buf, 31), 如果服务器只返回4个字节,既不关闭也不异常,那结果就是一直等待数据到来。
      If no messages are available at the socket, the receive calls wait for a message to  arrive, unless the socket is non-blocking。
      欢迎多讨论,欢迎多发现问题。
      

posted on 2012-03-09 21:24 冰果 阅读(1361) 评论(3)  编辑 收藏 引用

评论

# re: recv行为描述错了 2012-03-10 15:36 春秋十二月

这个Read函数,前提是socket是blocking的,如果是no-blocking的话,就要搭配select了  回复  更多评论   

# re: recv行为描述错了 2012-05-09 14:18 天下

你要这样用的话,一个参数就可以了,何必这么麻烦
在阻塞的方式下:
注意recv的最后一个参数:MSG_WAITALL  回复  更多评论   

# re: recv行为描述错了[未登录] 2012-05-10 11:14 春秋十二月

@天下
不带超时用MSG_WAITALL是不错的选择 唯一的问题可能是底层支持及跨平台与否   回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理