Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using write()/read() on UDP socket?

Tags:

c

linux

sockets

udp

According to the man pages:

The only difference between send() and write(2) is the presence of flags. With a zero flags argument, send() is equivalent to write(2). Also, the following call send(sockfd, buf, len, flags); is equivalent to sendto(sockfd, buf, len, flags, NULL, 0);

and

The recv() call is normally used only on a connected socket (see connect(2)) and is identical to recvfrom() with a NULL src_addr argument.

Also, if I'm not wrong (couldn't find it in the man pages), recv with flags == 0 is equivalent to read (analogue to write and send).


So:

  • does this mean, that using readon a UDP socket is perfectly fine (if I don't need the src_addr)?
  • is there a way to use write on UDP socket (as now I set the destination address in sendto's dest_addr parameter)?
like image 487
Kiril Kirov Avatar asked Nov 13 '14 13:11

Kiril Kirov


People also ask

Does RECV work with UDP?

Unlike send(), the recv() function of Python's socket module can be used to receive data from both TCP and UDP sockets.

What does connect () do on a UDP socket?

Datagram (UDP) sockets. The CONNECT command enables an application to associate a socket with the socket name of a peer. The socket then is considered to be a connected UDP socket. You can call the CONNECT command multiple times with different peer names to change the socket association.

How do you specify socket type for UDP?

The steps of establishing a UDP socket communication on the server side are as follows: Create a socket with the socket() function; Bind the socket to an address using the bind() function; Send and receive data by means of recvfrom() and sendto().

How do I bind a UDP socket to an IP address?

You would do this with the bind() function: int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); The first parameter is the file descriptor for the socket. The second is a pointer to a socket address structure which contains (for IPv4 or IPv6) the IP address and port to bind to.


2 Answers

  • Using read() on a UDP socket is perfectly fine if you don't need the source address.
  • You can use write() if you connect() the UDP socket to the destination.
like image 55
user207421 Avatar answered Oct 05 '22 02:10

user207421


Also, if I'm not wrong (couldn't find it in the man pages), ::recv with flags == 0 is equivalent to ::read (analogue to ::write and ::send)

Yes it is correct if the file descriptor is a socket: send/recv will fail otherwise with EBADF.
And it is also true that in a connection-oriented model send is equivalent to sendto and recv to recvfrom with NULL sockaddr * because the protocol already provides them.

With UDP, however, there's no connection so a call like this:

// assume fd to be an UDP socket
write(fd, buff, bytes) 

would not make sense as no destination is provided (EDESTADDRREQ). Instead, when you read a packet, you know where it is coming from and you may want to use that IP in case something looks wrong, for istance.

My advise is:

  • Use send/recv if you're in a connection oriented mode e.g. TCP
  • Use sendto/recvfrom mainly for connectionless communications e.g UDP
  • Use write/read if you will not specify any flag and for raw I/O (the aforementioned functions may be consider as higher level ones)

I would not advise a single class which handles both protocols but rather two specialized ones; don't mix the protocols.

like image 37
edmz Avatar answered Oct 05 '22 02:10

edmz