免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4602 | 回复: 6
打印 上一主题 下一主题

[C] 新手求教socket接收数据怎么判断结束? [复制链接]

论坛徽章:
2
综合交流区版块每日发帖之星
日期:2016-02-16 06:20:00每日论坛发贴之星
日期:2016-02-16 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-10-07 15:29 |只看该作者 |倒序浏览
发送端

        if(sendto(sock,xmlbuf,strlen(xmlbuf)+1,0,(struct sockaddr *)&rsock,sizeof(rsock)) == -1){  
            printf("Sendto failed!\n");  
            exit(2);      
          }
    bzero(file_name, 1024*1000);
    if ( (iRecvLen = tcp_raw_recv(sock, file_name, 1024)) < 0 )
    {
        fprintf(stderr, "tcp_raw_recv data error!!!\n");
    //    tcp_close(iSock);
    }
    printf("aaaa ???");
    printf("file_name=%s\n",file_name);


接收端
int tcp_raw_recv(int sock, char *buf, int maxlen)
{
    int rch = 0;
    int a = 0;
    void *bbuf = malloc(maxlen);

    while((a = read(sock, bbuf, maxlen)) > 0){
    rch = rch + a;
    sprintf(buf,"%s%s", buf, bbuf);
    if( a < 0 || (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)){break;}
    }
    return rch;
}

接收端阻塞了,该怎么解决!

论坛徽章:
1
15-16赛季CBA联赛之广夏
日期:2016-12-27 17:00:39
2 [报告]
发表于 2016-10-08 09:10 |只看该作者
接收端阻塞说明你发送端没有发送数据啊。你将发送端进程终止,就可以退出接收端read状态。

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2016-10-08 09:28 |只看该作者
TCP没有边界的,发的时候插入“边界”,收的时候检查“边界”

论坛徽章:
0
4 [报告]
发表于 2016-10-12 10:56 |只看该作者
一般接收数据有开始标志(比如0xfffe),数据包,和结束标志(0xffae),并且要有crc32校验来确保

论坛徽章:
0
5 [报告]
发表于 2016-10-25 17:36 |只看该作者
什么叫“结束”?  这是应用层协议制定者需要事先制定出来的。

比如HTTP协议,要根据头的信息,来分析后面content的长度,或者chunked的方式,来决定什么时候结束传输。

TCP协议是运输层协议,它当然不可能知道上层(应用层)协议什么时候结束了。

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-08-14 06:20:00
6 [报告]
发表于 2016-11-09 00:02 |只看该作者
socket是阻塞的啊,没有数据当然会阻塞在read了。要不改为非阻塞socket,要不定义一个协议,比如每段数据前4个字节放数据长度,这样就知道接收端有没有读完,读完就处理。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
7 [报告]
发表于 2016-11-22 22:27 |只看该作者
本帖最后由 wlmqgzm 于 2016-11-22 22:29 编辑

发送端执行socket_shutdown_send, 那么接收端就会收到EOF标志, 表示文本结束返回, 接收端程序就会正常返回, 就这么简单.
TCP/IP协议已经考虑了通知机制. 前面的很多回答都不正确

int  Asio_tcp_socket::socket_shutdown_send( boost::asio::ip::tcp::socket &socket1, int  int_socket_handle_init )
{
  boost::system::error_code ec;
  socket1.shutdown( boost::asio::ip::tcp::socket::shutdown_send, ec );
  if( ec )   {
    if( g_message_out_level>=2 )  {
      int value =  ec.value();
      std::string str_msg   = "socket=";
      str_msg += std::to_string( int_socket_handle_init );
      str_msg +=  ", error value=";
      str_msg += std::to_string( value );
      str_msg +=  ", error=";
      str_msg += ec.message();
      warn_message_str( str_msg );
      }
    return -1;
    }
  if( g_message_out_level>=5 )  log_message_int(" shutdown send. socket", int_socket_handle_init );
  return 0;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP