3

I am using recvfrom() and sendto() for receiving and sending UDP packets.

I have noticed that recvfrom() as last parameter requires a pointer to the variable storing the length of server address while sendto() requires the variable that stores the length of the client address.

Why there is this difference?

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39

2 Answers2

3

I have noticed that recvfrom() as last parameter requires a pointer to the variable storing the length of server address while sendto() requires the variable that stores the length of the client address.

You actually answering your own question

recvfrom() as last parameter requires a pointer to
the variable storing the length of server address.


while sendto() requires the variable that stores 
the length of the client address.

recvfrom() needs pointer because it is storing the value to the location where that pointer is pointing . Since in c there is nothing called call by reference you need to pass the pointer to simulate call-by-reference behavior.

kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
  • 2
    That's basically correct, but note that "call-by-reference" is a quite general/abstract concept, which one can see as being _implemented_ by passing pointers as function arguments in C. So, it is quite ok to say "c supports call by reference" – Ctx Oct 18 '19 at 12:27
  • 2
    @Ctx no that's wrong. C only support call-by-value. You can emulate call-by-ref passing pointers, but that does not make C supporting it (it isn't native to the language). – Jean-Baptiste Yunès Oct 18 '19 at 12:30
  • Thank you Kiran Biradar for your answer and thank Jean-Baptise Yunes. Why recvfrom needs the location where the pointer is pointing while sendto does not? – Tommaso Bendinelli Oct 18 '19 at 12:32
  • @Jean-BaptisteYunès That's a very narrow sight on those concepts, typical for programmers. – Ctx Oct 18 '19 at 13:49
2

Since UDP is not connection based (there's not a connect(sd, ...) call in which you say: from now on all data related to socket descriptor sd will come from a well known IP-port couple), whenever you issue recvfrom() it will (try to) return you the address from where incoming data origins.

It writes the address in src_addr buffer, if it is not NULL. This buffer is provided by the caller and its size must be specified setting addr_len parameter. It is passed by pointer because recvfrom(), after using it to limit the amount of data written in src_addr, will overwrite it with the actual address length. We can say that addr_len is an input-output parameter.

The caller of sendto(), on the other side, will exactly know the destination address, so addr_len in this case is passed by value because is an input-only parameter.

This information is clearly explained in the guide you linked in the question.

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
  • Thank you! I got lost through the jargon words and thus the guide was not really useful. So the reason is that the **actual** address length is known due to UDP network of not being connection based. Thus we are passing by pointer because this value can be modified. – Tommaso Bendinelli Oct 18 '19 at 12:38
  • 1
    Actually **there _is_ an option to call connect() on UDP** to specify the (only) remote address (but not actually communicate like TCP does with the SYN/ACK exchange) and subsequently use send() and recv() with that address implicit; see https://linux.die.net/man/7/udp et rel. But sendto() recvfrom() sendmsg() recvmsg() _without_ connect() are more commonly used and work as you describe. – dave_thompson_085 Oct 18 '19 at 13:00