What is the Difference Between read() and recv() , and Between send() and write()?

CSocketsUnixNetwork ProgrammingPosix

C Problem Overview


What is the difference between read() and recv(), and between send() and write() in socket programming in terms of performances, speed and other behaviors?

C Solutions


Solution 1 - C

The difference is that recv()/send() work only on socket descriptors and let you specify certain options for the actual operation. Those functions are slightly more specialized (for instance, you can set a flag to ignore SIGPIPE, or to send out-of-band messages...).

Functions read()/write() are the universal file descriptor functions working on all descriptors.

Solution 2 - C

Per the first hit on Google

> read() is equivalent to recv() with a flags parameter of 0. Other values for the flags parameter change the behaviour of recv(). Similarly, write() is equivalent to send() with flags == 0.

Solution 3 - C

read() and write() are more generic, they work with any file descriptor. However, they won't work on Windows.

You can pass additional options to send() and recv(), so you may have to used them in some cases.

Solution 4 - C

I just noticed recently that when I used write() on a socket in Windows, it almost works (the FD passed to write() isn't the same as the one passed to send(); I used _open_osfhandle() to get the FD to pass to write()). However, it didn't work when I tried to send binary data that included character 10. write() somewhere inserted character 13 before this. Changing it to send() with a flags parameter of 0 fixed that problem. read() could have the reverse problem if 13-10 are consecutive in the binary data, but I haven't tested it. But that appears to be another possible difference between send() and write().

Solution 5 - C

Another thing on linux is:

send does not allow to operate on non-socket fd. Thus, for example to write on usb port, write is necessary.

Solution 6 - C

On Linux I also notice that :

> Interruption of system calls and library functions by signal handlers
> If a signal handler is invoked while a system call or library function call is blocked, then either: > > * the call is automatically restarted after the signal handler returns; or > > * the call fails with the error EINTR.

>... The details vary across UNIX systems; below, the details for Linux. > > > If a blocked call to one of the following interfaces is interrupted > by a signal handler, then the call is automatically restarted after > the signal handler returns if the SA_RESTART flag was used; otherwise the call fails with the error EINTR:

> * read(2), readv(2), write(2), writev(2), and ioctl(2) calls on "slow" devices.

> .....

> The following interfaces are never restarted after being interrupted by a signal handler, regardless of the use of SA_RESTART; they always fail with the error EINTR when interrupted by a signal handler:

> * "Input" socket interfaces, when a timeout (SO_RCVTIMEO) has been set on the socket using setsockopt(2): accept(2), recv(2), recvfrom(2), recvmmsg(2) (also with a non-NULL timeout argument), and recvmsg(2).

> * "Output" socket interfaces, when a timeout (SO_RCVTIMEO) has been set on the socket using setsockopt(2): connect(2), send(2), sendto(2), and sendmsg(2).

Check man 7 signal for more details.


A simple usage would be use signal to avoid recvfrom blocking indefinitely.

An example from APUE:

#include "apue.h"
#include <netdb.h>
#include <errno.h>
#include <sys/socket.h>

#define BUFLEN		128
#define TIMEOUT		20

void
sigalrm(int signo)
{
}

void
print_uptime(int sockfd, struct addrinfo *aip)
{
	int		n;
	char	buf[BUFLEN];

	buf[0] = 0;
	if (sendto(sockfd, buf, 1, 0, aip->ai_addr, aip->ai_addrlen) < 0)
		err_sys("sendto error");
	alarm(TIMEOUT);
    //here
	if ((n = recvfrom(sockfd, buf, BUFLEN, 0, NULL, NULL)) < 0) {
		if (errno != EINTR)
			alarm(0);
		err_sys("recv error");
	}
	alarm(0);
	write(STDOUT_FILENO, buf, n);
}

int
main(int argc, char *argv[])
{
	struct addrinfo		*ailist, *aip;
	struct addrinfo		hint;
	int					sockfd, err;
	struct sigaction	sa;

	if (argc != 2)
		err_quit("usage: ruptime hostname");
	sa.sa_handler = sigalrm;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGALRM, &sa, NULL) < 0)
		err_sys("sigaction error");
	memset(&hint, 0, sizeof(hint));
	hint.ai_socktype = SOCK_DGRAM;
	hint.ai_canonname = NULL;
	hint.ai_addr = NULL;
	hint.ai_next = NULL;
	if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0)
		err_quit("getaddrinfo error: %s", gai_strerror(err));

	for (aip = ailist; aip != NULL; aip = aip->ai_next) {
		if ((sockfd = socket(aip->ai_family, SOCK_DGRAM, 0)) < 0) {
			err = errno;
		} else {
			print_uptime(sockfd, aip);
			exit(0);
		}
	}

	fprintf(stderr, "can't contact %s: %s\n", argv[1], strerror(err));
	exit(1);
}

Solution 7 - C

"Performance and speed"? Aren't those kind of ... synonyms, here?

Anyway, the recv() call takes flags that read() doesn't, which makes it more powerful, or at least more convenient. That is one difference. I don't think there is a significant performance difference, but haven't tested for it.

Solution 8 - C

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

Solution 9 - C

you can use write() and read() instead send() and recv() but send() and recv() offer much greater control over your data transmission

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSajad BahmaniView Question on Stackoverflow
Solution 1 - CGonzaloView Answer on Stackoverflow
Solution 2 - CJonathan FeinbergView Answer on Stackoverflow
Solution 3 - CBastien LéonardView Answer on Stackoverflow
Solution 4 - CajbView Answer on Stackoverflow
Solution 5 - CMert MertceView Answer on Stackoverflow
Solution 6 - CRickView Answer on Stackoverflow
Solution 7 - CunwindView Answer on Stackoverflow
Solution 8 - CMustapha RachidiView Answer on Stackoverflow
Solution 9 - CMustapha RachidiView Answer on Stackoverflow