如何使用read()重新创建recv()?

如何使用read()重新创建recv()?,c,sockets,recv,low-level-io,C,Sockets,Recv,Low Level Io,由于规范要求,我不允许使用recv()或类似函数来读取套接字的fd。我想知道如何使用read()重新生成该函数 我尝试用以下代码创建它 int recvFromFd(int connectionFd, char *buf, int size) { char c; int i = 0; for (read(connectionFd, &c, 1); i < size; i++) { buf[i] = c; if (c =

由于规范要求,我不允许使用recv()或类似函数来读取套接字的fd。我想知道如何使用read()重新生成该函数

我尝试用以下代码创建它

int recvFromFd(int connectionFd, char *buf, int size)
{
    char c;
    int i = 0;
    for (read(connectionFd, &c, 1); i < size; i++)
    {
        buf[i] = c;
        if (c == '\n' || read(connectionFd, &c, 1) == EOF)
            break;
    }
    return i;
}
int recvFromFd(int connectionFd,char*buf,int size)
{
字符c;
int i=0;
for(读取(connectionFd,&c,1);i
这段代码在一定程度上是有效的,但通常当发送者发送一条又一条消息时,函数会同时将这两条消息读取到同一个缓冲区(附件)。

在Unix上可以使用read(2)代替recv(2)(但我不确定它是否在Windows上有效,因为Windows上没有read()函数)。但是read()函数有一些限制:

  • 您无法获取对等方的地址(在UDP协议的情况下)

  • 无法接收零大小的数据报(UDP)

  • 无法传递文件描述符(通过unix域套接字)

  • 您不能使用用于从内核获取网络配置的特殊套接字类型(AF_NETLINK domain、SOCK_SEQPACKET socket type)

  • Linux手册页上说:

    recv()和read(2)之间的唯一区别在于 旗帜。对于零标志参数,recv()通常相当于 读(2)


    正如我所想,对于TCP协议,在使用read(2)或recv(2)时几乎没有区别。

    所以我最后做了以下工作,它工作了

    int recvFromFd(int connectionFd, char *buf, int size)
    {
        char c;
        int i = 0;
        for (read(connectionFd, &c, 1); i < size && c != '\n'; i++)
        {
            buf[i] = c;
            read(connectionFd, &c, 1);
        }
        buf[i] = '\0';
        if (debugMode)
            printf("\n>Incoming from socket: %s\n", buf);
        return i; // how many was read
    }
    
    int recvFromFd(int connectionFd,char*buf,int size)
    {
    字符c;
    int i=0;
    for(读取(connectionFd,&c,1);i从套接字传入:%s\n”,buf);
    return i;//读取了多少个
    }
    
    那里使用的是哪种连接?数据报?流动?看起来您正在尝试实现消息流中的消息传递,这需要消息的精确格式。只要
    recv()
    的flags参数为0,并且您不在Windows上或处理0长度的数据报,它和
    read()
    是可交换的。看起来您真正的问题是“我如何从套接字中读取一行文本”@Jean BaptisteYunès sockets tcp connections.@Shawn windows上的Ubuntu终端如何?如果Linux手册页上是这么说的,它与你的第二点相矛盾。你能给我解释一下零大小的数据报吗?在一边你可以调用send(socket),“,0,0)。这对TCP套接字不起任何作用,但在UDP套接字中,它会向网络发送不同的UDP数据包,而没有有效负载。可以通过调用recvmsg(2)函数在接收端检测到此类数据包。read(2)和recv(2)等函数无法区分大小为零的数据报和“文件结束”条件(当函数返回零时),或缺少数据(在非阻塞套接字的情况下)。在某些协议中,零大小的数据报用作“记录结束”标记,作为发送“带外”数据的方式。这一切都很好,但您在没有证据的情况下声称
    read()
    无法提供零长度数据报,这与您引用的Linux页面完全矛盾。在接收到零长度数据报的情况下,read(2)返回零。因此您无法将这种情况与文件结尾区分开来。我知道这一点,因为“netcat”“在接收到大小为零的数据报时终止。可能这是linux特有的东西,其他Unice有不同的行为。我不知道。