How do I recreate the recv() with read()?

211 Views Asked by At

Because of specifications requirement, I'm not allowed to use recv() or similar functions to read from socket's fd. I was wondering how I would remake that function using read()?

I've attempted creating it with the following code

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;
}

This code works to an extent, but often when when the sender send one message after another, the function read both of those message at the same time to the same buffer (appends).

2

There are 2 best solutions below

5
Kirill Frolov On

You can use read(2) in place of recv(2) on Unix (but I'm not sure if it works on Windows, where is no read() function). But read() function has some limitations:

  1. You can't get peer's address (in case of UDP protocol);

  2. You can't receive zero sized datagrams (UDP);

  3. You can't pass file descriptors (via unix domain socket);

  4. You can't work with special socket types (AF_NETLINK domain, SOCK_SEQPACKET socket type), which is used to obtain network configuration from the kernel.

Linux manpage says:

The only difference between recv() and read(2) is the presence of flags. With a zero flags argument, recv() is generally equivalent to read(2).

As I think, for TCP protocol where is almost no difference in use of read(2) or recv(2).

0
user10416282 On

So I ended up doing the following and it works.

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
}