Chinaunix

标题: send 和 recv 函数问题 [打印本页]

作者: oract666    时间: 2008-09-05 19:19
标题: send 和 recv 函数问题
服务器端通过while来循环调用send函数批量把一个c 的struct的集合传递到server端,server 端在一个while 循环中用recv函数来接收send过来的数据,有数据的时候就recv没有数据的话自然阻塞在recv调用上,server端是迭代服务器没有做fork模式的并发服务器。

但是最近却发现了一个问题,在客户端数量很多的时候recv过来的struct中经常会少数据,有些struct成员就是空白的,请问为什么会发生这个问题呢???
作者: oract666    时间: 2008-09-05 19:23
标题: 回复 #1 oract666 的帖子
后来修改了程序,在客户端每次调用send之后都sleep 一秒钟,就发现数据都正常了。
作者: tyc611    时间: 2008-09-05 19:27
检查发送/接收成功的字节数,
1,确保数据都成功发送了
2,确保接收到了所有欲接收的数据
作者: oract666    时间: 2008-09-05 19:33
原帖由 tyc611 于 2008-9-5 19:27 发表
检查发送/接收成功的字节数,
1,确保数据都成功发送了
2,确保接收到了所有欲接收的数据



我send 后打印了send函数的返回值,发现返回值都是完整的数据包长度
在recv后也打印了recv的函数返回值,发觉其中有好几个都小于完整数据包的长度
我send和recv'的第三个参数len都是固定的完整数据包长度,请问这用什么方法可以确保recv的完整性呢??
作者: gawk    时间: 2008-09-05 19:35
没读完为什么不继续读?
作者: tyc611    时间: 2008-09-05 19:41
原帖由 oract666 于 2008-9-5 19:33 发表



我send 后打印了send函数的返回值,发现返回值都是完整的数据包长度
在recv后也打印了recv的函数返回值,发觉其中有好几个都小于完整数据包的长度
我send和recv'的第三个参数len都是固定的完整数据包长 ...

用循环,直接发送或者接收完毕
作者: oract666    时间: 2008-09-05 20:00
原帖由 tyc611 于 2008-9-5 19:41 发表

用循环,直接发送或者接收完毕


请问循环是怎么使用? 这样可以吗:

while(1)
     {
             bzero(&myinfo,sizeof(info));
             ircv=recv(connfd,&myinfo,sizeof(myinfo),0);
             while( (ircv>0) && (ircv<sizeof(myinfo)) )
                ircv=ircv+recv(connfd,&myinfo+ircv,sizeof(myinfo)-ircv,0);
             if(ircv>0)
              {
                     printf("\n%s,%d\n",myinfo.info1,ircv);
              }
             else if(ircv<=0)
                  {
                      close(connfd);
                      break;
                  }
      }

[ 本帖最后由 oract666 于 2008-9-5 20:01 编辑 ]
作者: oract666    时间: 2008-09-05 20:01
原帖由 gawk 于 2008-9-5 19:35 发表
没读完为什么不继续读?


菜鸟级,呵呵
作者: oract666    时间: 2008-09-05 20:15
原帖由 oract666 于 2008-9-5 20:00 发表


请问循环是怎么使用? 这样可以吗:

while(1)
     {
             bzero(&myinfo,sizeof(info));
             ircv=recv(connfd,&myinfo,sizeof(myinfo),0);
             while( (ircv>0) && (ir ...



如此也有问题,我用了MSG_WAITALL 参数,没用循环解决了
但是很想知道如果循环的话究竟怎么用?呵呵
作者: oract666    时间: 2008-09-05 20:18
如果send一个很大的buf的时候是否也存在一次send的字节数不等于数据包实际大小的情况呢?
是否也要通过循环send或者设置什么参数来解决呢?
作者: tyc611    时间: 2008-09-05 20:19
原帖由 oract666 于 2008-9-5 20:15 发表



如此也有问题,我用了MSG_WAITALL 参数,没用循环解决了
但是很想知道如果循环的话究竟怎么用?呵呵

循环差不多就是那么用的,有问题是啥?
作者: oract666    时间: 2008-09-05 20:21
原帖由 tyc611 于 2008-9-5 20:19 发表

循环差不多就是那么用的,有问题是啥?



我这么用循环接收会出现ircv数大于数据包大小的情况,数据也是乱的,倒是MSG_WAITALL最管用
是不是我的循环有问题?
作者: tyc611    时间: 2008-09-05 20:27
原帖由 oract666 于 2008-9-5 20:21 发表



我这么用循环接收会出现ircv数大于数据包大小的情况,数据也是乱的,倒是MSG_WAITALL最管用
是不是我的循环有问题?

myinfo是结构体名?
如果是,将其转换为char*再与接收到的字节数相加
也就是ircv=ircv+recv(connfd,(char*)&myinfo+ircv,sizeof(myinfo)-ircv,0);
作者: oract666    时间: 2008-09-05 20:40
原帖由 tyc611 于 2008-9-5 20:27 发表

myinfo是结构体名?
如果是,将其转换为char*再与接收到的字节数相加
也就是ircv=ircv+recv(connfd,(char*)&myinfo+ircv,sizeof(myinfo)-ircv,0);



没错,这次转换指针后就成功了!
多谢!

顺便再请教一下send大数据是否也要循环?
作者: tyc611    时间: 2008-09-05 20:44
原帖由 oract666 于 2008-9-5 20:40 发表



没错,这次转换指针后就成功了!
多谢!

顺便再请教一下send大数据是否也要循环?

数据太大,也得循环,系统缓冲区有限
作者: oract666    时间: 2008-09-05 20:48
原帖由 tyc611 于 2008-9-5 20:44 发表

数据太大,也得循环,系统缓冲区有限



那就是说为了安全,send最好也要判断返回值大小和数据包的比较结果?
我现在有些应用根本没有判断就发走了,但是数据量很小一般几十个字节,MSG_WAITALL 参数同样适用于send吗?

呵呵,都是平时用tuxedo之类的习惯了,直接call。纯socket编程还是很多细节的啊
作者: tyc611    时间: 2008-09-05 20:54
原帖由 oract666 于 2008-9-5 20:48 发表



那就是说为了安全,send最好也要判断返回值大小和数据包的比较结果?
我现在有些应用根本没有判断就发走了,但是数据量很小一般几十个字节,MSG_WAITALL 参数同样适用于send吗?

呵呵,都是平时用tux ...

我用得也不多,基本上写好一个收发函数就不管了
MSG_WAITALL参数没用过,但如果是大数据,我想啥参数都不管用,因为系统缓冲区限制摆在那,直接你取走数据才有可用空间
所以还是最好都判断返回值,用循环做
作者: JohnBull    时间: 2008-09-05 22:08
我猜是因为部分写入,检查send的返回值。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2