inet-framework / inet

INET Framework for the OMNeT++ discrete event simulator
https://inet.omnetpp.org
Other
438 stars 485 forks source link

UDP Sockets #460

Open ManiAm opened 5 years ago

ManiAm commented 5 years ago

I was looking at the udpapp example.

2019-09-21_0-46-04

The way UDP socket is laid out is a little bit confusing especially for those who have done network socket programming.

  1. You are using the UdpSocketIo for both server and client processes.

  2. In the handleStartOperation of UdpSocketIo, three operations are performed (both in server and client): 1) setting socket options, 2) binding to local address and local port, and 3) connect

https://github.com/inet-framework/inet/blob/4461edad59f0bb85349261415e13e9953d9d7fcf/src/inet/applications/udpapp/UdpSocketIo.cc#L117

3. However, if you check BSD socket programming in any language (C/C++/Python/C#), there is no connect method for UDP. UDP is a connection-less transport layer protocol and does not connect to any remote entity. It just sends the datagram without any prior connection establishment.

Here is the flow for UDP client/server communication. UDP socket does not have the concept of connect. Moreover, binding is only used in the server process.

Picture1

  1. Connect function is used by the TCP socket and only in the client socket.

Picture2

Am I missing something here?


Edit: Apparently, you can use the connect method on a UDP socket, although it is a little bit weird, and has a different meaning/purpose than creating a connection!

https://stackoverflow.com/questions/6189831/whats-the-purpose-of-using-sendto-recvfrom-instead-of-connect-send-recv-with-ud

In that case, the only unusual practice is calling bind in both client and server processes. However, it seems that you name the class UdpSocketIo for a reason. IO at the end, apparently means that it can act both as client and server. Then, IO is a poorly chosen name.


One more thing: UdpBasicApp is supposed to run on a client device. Its counterpart is like UdpSink. Then why we call bind in the UdpBasicApp? If UdpBasicApp is supposed to send UDP datagrams, then why do we bother binding?

https://github.com/inet-framework/inet/blob/d0c8d74e2850e703afadd13b789313c4eec6e767/src/inet/applications/udpapp/UdpBasicApp.cc#L130

levy commented 5 years ago

The connect() method in INET's UdpSocket is used to remember the destination address/port to send to and receiver from. This is only a convenience feature.

If you look at the UdpSocketIo parameters, then you will see that the only parameter that is mandatory is the destPort. All others are optional and will have no effect by default. Although, the code could be updated to reflect that, I agree. The name IO may not be the best one, but we couldn't come up with something else that is general and short enough at the same time.

As for the UdpBasicApp, the bind call is indeed unnecessary, because the packets will be dropped either way.

ZoltanBojthe commented 5 years ago

udp(7) - Linux man page: When connect() is called on the socket, the default destination address is set and datagrams can now be sent using send() or write() without specifying a destination address.