免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: pineapple1175
打印 上一主题 下一主题

一个网络编程中send的菜鸟问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2006-12-26 20:55 |只看该作者
原帖由 cjaizss 于 2006-12-26 20:50 发表

楼主程序的问题不是出在这里


人家也没说出在这里啊,而且我都说了出在哪儿了啊……ft,你怎么老跟别人较劲阿……admire

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
12 [报告]
发表于 2006-12-26 20:57 |只看该作者
那我就说说LZ的愿意吧,LZ在那里阻塞等待128字节。
可是人家就发了5个字节。
所以服务器一直阻塞在recv上,直到客户端关闭,recv调用返回。

论坛徽章:
0
13 [报告]
发表于 2006-12-26 21:03 |只看该作者
原帖由 cjaizss 于 2006-12-26 20:57 发表
那我就说说LZ的愿意吧,LZ在那里阻塞等待128字节。
可是人家就发了5个字节。
所以服务器一直阻塞在recv上,直到客户端关闭,recv调用返回。


admire…………你这完全错误啊……
首先,strlen("hello") == 6而不是你说的5
其次,他while里第一次的recv已经收到了那6个字节,并没有产生能让人观察到的阻塞。但是它的while循环又执行了一遍recv(因为第一次recv的返回值>0),这第二次recv才产生了他所观察到的阻塞……
你说什么等待128字节根本就不对……

论坛徽章:
0
14 [报告]
发表于 2006-12-26 21:14 |只看该作者
原帖由 linyue 于 2006-12-26 21:03 发表
admire…………你这完全错误啊……
首先,strlen("hello") == 6而不是你说的5
其次,他while里第一次的recv已经收到了那6个字节,并没有产生能让人观察到的阻塞。但是它的while循环又执行了一遍recv(因为第一次recv的返回值>0),这第二次recv才产生了他所观察到的阻塞……
你说什么等待128字节根本就不对……


'h'
'e'
'l'
'l'
'o'
'\0'

其中,strlen(3) 在计算字符串长度的时候只算前面的五个字符,'\0' 没有算进去。

src/lib/libc/string/strlen.c:

size_t
strlen(str)
        const char *str;
{
        register const char *s;

        for (s = str; *s; ++s);
        return(s - str);
}


用红色标出的代码部分,表示对 s 进行反引用,判断到 *s 为非零就是跳出并终止 for 循环的条件。这个时候,'\0' 没有算进去。

论坛徽章:
0
15 [报告]
发表于 2006-12-26 21:17 |只看该作者
原帖由 langue 于 2006-12-26 21:14 发表


'h'
'e'
'l'
'l'
'o'
'\0'

其中,strlen(3) 在计算字符串长度的时候只算前面的五个字符,'\0' 没有算进去。

src/lib/libc/string/strlen.c:



用红色标出的代码部分,表示对 s 进行反引用,判 ...



不过不影响这个帖子的解决……
今天脑子进水了ft...

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
16 [报告]
发表于 2006-12-26 21:25 |只看该作者
哎,我脑子也进水了....
描述错误
人家发了5个字节在那里。
然后自己就recv返回了,然后人家再就没发数据了。
此时协议栈内缓冲区里已经没有数据了,但是人家又没有关闭,recv不好返回。终于人家关闭了连接,recv终于好返回了0代表人家已经关闭连接

论坛徽章:
0
17 [报告]
发表于 2006-12-26 21:28 |只看该作者
recv(2):

     If no messages are available at the socket, the receive call waits for a
     message to arrive, unless the socket is nonblocking (see fcntl(2))  in
     which case the value -1 is returned and the external variable errno set
     to EAGAIN.
The receive calls normally return any data available, up to
     the requested amount, rather than waiting for receipt of the full amount
     requested; this behavior is affected by the socket-level options
     SO_RCVLOWAT and SO_RCVTIMEO described in getsockopt(2).


这段文字,前一部分是楼主问题所在,后一部分是 15 楼 linyue 指出的。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
18 [报告]
发表于 2006-12-26 21:35 |只看该作者
阻塞的read(recv同理)不一定每次都会返回所希望读到的字节数,然而对与TCP,阻塞I/O时没有数据可读是不可返回的,除非对方主动关闭返回0。偶有的时候写设备驱动的时候read返回0不代表任何意思,只代表当前没有数据。然而对于TCP的这些I/O是一个标准

论坛徽章:
0
19 [报告]
发表于 2006-12-26 21:38 |只看该作者
原帖由 cjaizss 于 2006-12-26 21:35 发表
阻塞的read(recv同理)不一定每次都会返回所希望读到的字节数,然而对与 TCP,阻塞I/O时没有数据可读是不可返回的,除非对方主动关闭返回0。偶有的时候写设备驱动的时候read返回0不代表任何意思,只代表当前没有数据。然而对于TCP的这些I/O是一个标准  


对 socket descriptors 进行 close(),只是半关闭。返回 0,代表 EOF。两者联系起来,就不难理解了。

论坛徽章:
0
20 [报告]
发表于 2006-12-26 22:26 |只看该作者

回复 6楼 linyue 的帖子

才出去看了两个小时的书就有这么多回帖了,真是感激啊,再这之前的另外一个帖子上发了半天到现在也没人来理我
我去试了一下把while循环去掉直接send了一下就直接用recv接收就能正常运行了,不过apue2上面也明确说了: Since we're using a SOCK_STREAM socket, we can't be guaranteed that we will read the entire string in one call to recv, so we need to repeat the call until it returns 0.我那段while循环也是参照apue2上面的,假如我发送比较多的内容的话还是要用这种模式来接收的,还有就是nonblocking这种状态和blocking这种状态到底有什么区别??如果我非要用while循环接收那么代码要怎么改呢???
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP