socket read返回问题

MagicxiaoZ 2011-05-19 02:34:08
假设read一个socket,参数为100,read(socketfd, buf, 100),对方假设发送了80字节数据,但是现在socket接收缓冲区里只收到了20字节数据,问这个时候,read是否会返回20字节呢,还是继续阻塞等到剩余的60字节?
...全文
1024 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
jameszhanglei123 2011-05-21
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sun_phoenix 的回复:]

TCP协议是面向流的,read和write调用的返回值往往小于参数指定的字节数。对于read调用,如果接收缓冲区中有20字节,请求读100个字节,就会返回20。对于write调用,如果请求写100个字节,而发送缓冲区中只有20个字节的空闲位置,那么write会阻塞,直到把100个字节全部交给发送缓冲区才返回,但如果socket文件描述符有O_NONBLOCK标志,则write不阻塞,直接返回20……
[/Quote]
说的非常对,unp第三章,讲的很详细。再次温习了一下。
想起当初学命名管道时,open 非阻塞写将失败,非阻塞读总是能成功。
wangw89 2011-05-21
  • 打赏
  • 举报
回复
我想请教一个问题啊,为什么我用c编的在arm下发送5个数字,在delphi编写的界面程序下就收到4个呢?第一个数字没收到,但是我用c编写的程序可以收到全部的字符,是怎么回事呢?郁闷的我不行,望大家给个建议啊
CN_SK 2011-05-21
  • 打赏
  • 举报
回复
unp v2 第一章讲的就是read和write函数的封装,将其封装为readn和writen,保证在非错误的情况下写和读指定的大小。就是说如果你要接受100B,那么就会一直循环,知道接受到100B(错误和EOF除外):

static ssize_t readn(int fd, void *vptr, size_t n)
{
size_t nleft = n;
ssize_t nread;
char *ptr = vptr;

while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)/* interrupted by sig handler */
nread = 0; /* and call read() again */
else
return (-1); /* error */
} else if (nread == 0)
break; /* EOF */

nleft -= nread;
ptr += nread;
}
return (n - nleft); /* return >= 0 */
}

4楼和9楼说的是粘包问题的解决方法。比如qq消息,其长度不同,我们如何每次收取不同长度的包,如何知道我们是要收的这个包是100个字节还是120个字节,而不是错误的把两个包和到一起收了。
比如发送了两行,一行是“hello”,一行是“world!”,保证第一次读hello,第二次读world!
MagicxiaoZ 2011-05-20
  • 打赏
  • 举报
回复
Nice//
[Quote=引用 13 楼 sun_phoenix 的回复:]

TCP协议是面向流的,read和write调用的返回值往往小于参数指定的字节数。对于read调用,如果接收缓冲区中有20字节,请求读100个字节,就会返回20。对于write调用,如果请求写100个字节,而发送缓冲区中只有20个字节的空闲位置,那么write会阻塞,直到把100个字节全部交给发送缓冲区才返回,但如果socket文件描述符有O_NONBLOCK标志,则write不阻塞,直接返回20……
[/Quote]
Sun_Phoenix 2011-05-20
  • 打赏
  • 举报
回复
TCP协议是面向流的,read和write调用的返回值往往小于参数指定的字节数。对于read调用,如果接收缓冲区中有20字节,请求读100个字节,就会返回20。对于write调用,如果请求写100个字节,而发送缓冲区中只有20个字节的空闲位置,那么write会阻塞,直到把100个字节全部交给发送缓冲区才返回,但如果socket文件描述符有O_NONBLOCK标志,则write不阻塞,直接返回20
MagicxiaoZ 2011-05-20
  • 打赏
  • 举报
回复
想要点稍微详细的解释,困惑~~多谢啦//
[Quote=引用 8 楼 justkk 的回复:]

1.read马上返回20字节
[/Quote]
「已注销」 2011-05-20
  • 打赏
  • 举报
回复
一个包一个包的 底层收到整个数据才会去掉ip 协议 提供给上一层,比如udp接受,硬件收到20字节数据加前面的一些协议,会等到这个包后面数据一起 然后去掉IP协议 ,不然数据不对TCP/IP协议中IP协议的checksum 校验失败,所以堵塞 只会阻塞一个包 一个包的 底层会等你这个包完整了才会给上层。 所以是LZ的后面一种说话
MagicxiaoZ 2011-05-20
  • 打赏
  • 举报
回复
还有高人么?嘿//
njdy_2008 2011-05-19
  • 打赏
  • 举报
回复
通常的做法是:
应用发送数据的格式要协商好(也就是应用协议),
比如前4个字节表示数据长度,
先保证这4个自己受到后你就能根据制定的长度把数据接收下来了。

这样就能保证完整的数据包被接收下来了。
justkk 2011-05-19
  • 打赏
  • 举报
回复
1.read马上返回20字节
李亚超 2011-05-19
  • 打赏
  • 举报
回复
while(read(...))
{
//数据放入缓冲区
}
直到while结束循环,可以认为一个接受完成了
MagicxiaoZ 2011-05-19
  • 打赏
  • 举报
回复
就事论事的话,是1.read马上返回20字节呢?还是2.继续阻塞等待呢?
如果是阻塞等待的话,凭什么知道还有没收到的数据呢?
谢谢

[Quote=引用 4 楼 guosha 的回复:]

所以用TCP的自己定义的消息需要加一个头,定义自己的消息体长度是多少,来判断还有多少数据没有收完。
引用 3 楼 magicxiaoz 的回复:

引用 2 楼 magicxiaoz 的回复:

引用 1 楼 harry_lyc 的回复:

tcp的发送是没有数据边界的,一次发送100个字节,有可能一次接受100个字节,也有可能100次,一次接受1个字节。
接受多少,返回值就多少……
[/Quote]
断问天 2011-05-19
  • 打赏
  • 举报
回复
socket底层的TCP/IP就是用来保证能接收到一条完整的数据的, 不论是TCP还是UDP, 数据接收完了才会通知socket进行下一步动作, Qt的socket就是这样设计的, 其他的平台不太懂,估计差不多吧。
快乐田伯光 2011-05-19
  • 打赏
  • 举报
回复
所以用TCP的自己定义的消息需要加一个头,定义自己的消息体长度是多少,来判断还有多少数据没有收完。
[Quote=引用 3 楼 magicxiaoz 的回复:]

引用 2 楼 magicxiaoz 的回复:

引用 1 楼 harry_lyc 的回复:

tcp的发送是没有数据边界的,一次发送100个字节,有可能一次接受100个字节,也有可能100次,一次接受1个字节。
接受多少,返回值就多少
所以,TCP接受要一直等到没有数据为止


就是说继续阻塞等待剩下的80字节数据?
那接收端凭什么知道还有80字节数据没有到啊?


说……
[/Quote]
MagicxiaoZ 2011-05-19
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 magicxiaoz 的回复:]

引用 1 楼 harry_lyc 的回复:

tcp的发送是没有数据边界的,一次发送100个字节,有可能一次接受100个字节,也有可能100次,一次接受1个字节。
接受多少,返回值就多少
所以,TCP接受要一直等到没有数据为止


就是说继续阻塞等待剩下的80字节数据?
那接收端凭什么知道还有80字节数据没有到啊?
[/Quote]

说错了,通过什么判断出还有60字节数据没有到呢?
谢谢诸位//
MagicxiaoZ 2011-05-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 harry_lyc 的回复:]

tcp的发送是没有数据边界的,一次发送100个字节,有可能一次接受100个字节,也有可能100次,一次接受1个字节。
接受多少,返回值就多少
所以,TCP接受要一直等到没有数据为止
[/Quote]

就是说继续阻塞等待剩下的80字节数据?
那接收端凭什么知道还有80字节数据没有到啊?
李亚超 2011-05-19
  • 打赏
  • 举报
回复
tcp的发送是没有数据边界的,一次发送100个字节,有可能一次接受100个字节,也有可能100次,一次接受1个字节。
接受多少,返回值就多少
所以,TCP接受要一直等到没有数据为止

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧