什么可以限制从read()读入的字节

时间:2012-12-11 11:45:11

标签: sockets

我正在读取像这样初始化的套接字的字节:

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

但是当我从这个插座读取时

char buf[ETH_FRAME_LEN]
len = read(fd, buf, sizeof(buf));

len显示只读取了1500个字节。我检查了wireshark,返回的数据包是5854.IP下的总长度字段为5840(因此,以太网标头为+ 14字节= 5854)。我尝试使用更大的缓冲区(6000),但仍然只有1500字节被读取。

我尝试从服务器请求一个较小的文件(1504字节),但我得到了相同的结果。由于它是一个原始套接字,读入的数据包括以太网头,因此它不会将最后4个字节读入缓冲区。

这可能是什么原因?我不知道socket()可能引起这种情况的任何争论。

3 个答案:

答案 0 :(得分:1)

如果您再次尝试拨打read会怎样?快速返回消息的下一个块吗?

阅读man page(我的重点)

  

read()尝试读取 计数字节

如果您想读取一定数量的字节,您应该准备好在循环中拨打read,直到您通过电话累计收到目标总数。

答案 1 :(得分:1)

正在发生的事情是,每次拨打read(),您只能获得一个以太网MTU的有效负载。

答案 2 :(得分:1)

read()返回:

  

成功时,返回读取的字节数(零表示结束          文件),文件位置按此编号前进。 不是          如果此数字小于请求的字节数,则出错;          例如,这可能发生,因为实际可用的字节更少          现在(也许是因为我们接近文件结尾,或者因为我们          从管道或终端读取,或因为read()是          被信号打断了。出错时,返回-1,并设置errno          适当。在这种情况下,文件是否未指定          位置(如果有的话)改变。

您可以尝试将recv() MSG_WAITALL 一起使用,而不是使用纯read()

  

此标志请求操作块直到满                 请求得到满足。但是,通话可能仍然会减少                 如果捕获到信号,发生错误或断开连接,或者要接收的下一个数据是不同的,则请求数据                 类型比返回的类型。

len = recv(fd, buf, sizeof(buf), MSG_WAITALL);

另一种方法是在循环中读取或恢复,如:

ssize_t Recv(int fd, void* buf, ssize_t n)
{
    ssize_t read = 0;
    ssize_t r;
    while(read != n)
    {
        r = recv(fd, ((char*)buf)+read, n-read, 0);
        if(r == -1)
            return (read) ? read : -1;
        if(r == 0)
            return 0;

        read += r;
    }

    return read;
}