套接字:read()函数返回的长度不正确

时间:2009-07-13 09:59:49

标签: sockets

我是套接字编程的新手。我的函数调用类似于:

len = read(FD, buf, 1500);

[负责从telnet连接读取数据]

下一行中的printf显示buf长度为> 300个字符,但(int)len仅给出89个!因此,返回的字符串的所有进一步解析都失败了。

我读了很多关于异步套接字读取返回少于所需数据的问题,但在上面的情况下它返回了足够的数据,但报告的长度都是错误的[返回的字符串总是相同的,长度总是相同的错误的价值] ......

当返回的字符串很小(通常在100个字符的范围内)时,上述功能也能正常工作

任何指针都会非常有用!

- 阿斯温

4 个答案:

答案 0 :(得分:2)

您可以使用以下方法将读取偏移处的缓冲区归零:

buf[len] = 0;

打印电话应该没问题。

答案 1 :(得分:1)

通常,对于异步套接字,您必须先读取,直到收到所需的字节数。这意味着您必须管理缓冲区。 (即根据接收的字节等增加缓冲区指针)

您对缓冲区具有正确数据量但报告错误大小的观察结果可能是由上一次运行的陈旧数据引起的。确认您可以在每次运行前清除缓冲区。

答案 2 :(得分:1)

  

但在上述情况下,它返回了足够的数据,但报告的长度都是错误的

不,你错了。它正在返回它所说的返回,89字节。问题是这89个字节不包含一个nul终结符,因此,当你printf缓冲区时,它会继续运行,在read发生之前打印已经存在于缓冲区其余部分的内容。

你应该做什么(但请参见下面的警告)类似于:

len = read(FD, buf, 1500);
printf ("%*.*s\n", len, len, buf);

确保不要在缓冲区末尾打印。

您所看到的相当于:

char buff[500];
strcpy (buff, "Hello there");
memcpy (buff, "Goodbye", 7);
printf ("%s", buff);

因为你没有在memcpy中传输nul字符,所以剩下的缓冲区是:

               +---+---+---+---+---+---+---+---+---+---+---+---+
After sprintf: | H | e | l | l | o |   | t | h | e | r | e | \0|
               +---+---+---+---+---+---+---+---+---+---+---+---+
After memcpy : | G | o | o | d | b | y | e | h | e | r | e | \0|
               +---+---+---+---+---+---+---+---+---+---+---+---+

给出字符串"Goodbyehere"

警告:

如果您的数据流中有空字符,那么printf将无效,因为它将停在它找到的第一个零字符处。 read函数从文件描述符中读取二进制数据,而不必在第一个换行符或零字符处停止。

这相当于:

char buff[500];
strcpy (buff, "Hello there");
memcpy (buff, "Go\0dbye", 8);
printf ("%s", buff);

               +---+---+---+---+---+---+---+---+---+---+---+---+
After sprintf: | H | e | l | l | o |   | t | h | e | r | e | \0|
               +---+---+---+---+---+---+---+---+---+---+---+---+
After memcpy : | G | o | \0| d | b | y | e | \0| e | r | e | \0|
               +---+---+---+---+---+---+---+---+---+---+---+---+

给出字符串"Go"

如果确实想要在二进制通道上处理以nul或换行符结尾的字符串,则以下(伪代码)是一种方法:

while true:
    while buffer has no terminator character:
        read some more data into buffer, break on error or end-of-file.
    break on error or end-of-file.
    while buffer has at least one terminator character:
        process data up to first terminator character.
        remove that section from buffer.

这是一个在您拥有至少一个“工作单元”之前读取数据的过程,然后处理这些工作单元,直到您没有完整的工作单元为止。

答案 3 :(得分:0)

read()尝试从文件描述符FD读取最多1500个字节到缓冲区,从buf开始。成功时,返回读取的字节数。 如果此数字小于请求的字节数,则不是错误;这可能发生,例如因为现在实际可用的字节数较少(可能是因为我们接近文件结尾

通常,您需要在循环内调用读取。