Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to UDP send and receive on same port?

Tags:

c++

sockets

I need to be able to send and receive UDP packets on the same port. I am able to listen, on say port 5000, but my send uses a random high port. The system I am working written in VB with does this and my need is to write a UDP responder for debugging various protocol issues.

I am using the Open Source C++ Sockets Library from http://www.alhem.net (Anders Hedstrom) and have been able to use the UdpSocket::Bind() to receive incoming UDP packets using the virtual function UdpSocket::OnRawData(), but have been unable to cause the UdpSocket::Open() (calls connect) to make the UdpSocket::Send() use the port chosen in Bind() (it uses random high number port instead).

Moving the Open() function doesn't help. I have posted a request on their forum - but believe from what I have read that it should be possible to do this, and I'm probably not understanding how to use UDP.

Does anyone have any ideas on what I should try?
--thanks--

like image 982
cedgriss Avatar asked Oct 28 '09 22:10

cedgriss


People also ask

Can I send and receive UDP on the same port?

TCP vs UDP Once connected, a TCP socket can only send and receive to/from the remote machine. This means that you'll need one TCP socket for each client in your application. UDP is not connection-based, you can send and receive to/from anyone at any time with the same socket.

Can you send and receive on the same port?

A physical port can and is used for receiving and transmitting unless the port has been specifically configured to half-duplex.

Can UDP be bidirectional?

Datagram sockets allow processes to use UDP to communicate. A datagram socket supports bidirectional flow of messages. A process on a datagram socket can receive messages in a different order from the sending sequence and can receive duplicate messages. Record boundaries in the data are preserved.

Can you use Send with UDP?

UDP sockets can be connected or unconnected - in the first case send should be used and in the second sendto . This does not affect the protocol used, i.e. it still is unreliable UDP. It only affects where the destination is taken from: from the socket or given as argument.


2 Answers

System consists of a number of nodes listening on same port (different ip addr's). System [A] sends datagram to System [B]. System [B] asynchronously responds and send datagram(s) back to [A] all using same port. Even if [B] identifies [A]'s port, [A] is not listening on that port

I'm not sure I understand the "all using the same port" phrase in that sentence. If A sends a datagram to B, B will know A's IP and port right away (a quick check of your library documentation reveals OnRawData has a struct sockaddr *sa parameter, if you cast it to sockaddr_in* you'll be able to extract the IP:port pair). You can use that IP:port to send datagrams to and A will receive them. A is not "listening" on that port in the sense that it haven't called listen() on the socket, but since A owns a socket that is bound to that port (whether explicitly by calling bind() or assigned random port by the OS) it will receive the data.

Now if you want ALL your communication between nodes to go through your fixed port, you can do that. You just have to send all your datagrams through your "listening" socket. If every node "listens" on the same port, it means every node owns a socket that is bound to that port. If you want datagrams sent from A to B to appear coming from this fixed port you have to send them through that socket. I'm guessing that's why bind() doesn't work for your sending socket - A has a socket bound to port X, then you create another socket and try to bind it to the same port X, bind() fails since the port is already taken (and you don't check for errors :), and then the OS assigns random free port above 1024.

Note 1: I use "listening" in quotes everywhere, because the concept is not very clear in the context of UDP sockets. Once you have created socket and bound it to a port, either by calling bind() explicitly or by sending data and letting the OS bind it to a port, you can receive data from everywhere through it. No listen() or accept() calls needed.

Note 2: You say that UdpSocket::Open() calls connect(), but that doesn't make much sense - connect() does very little for UDP sockets - it merely establishes a default address so you can use send() instead of sendto() and not specify address on every send.

Hope that clears things up.


Edit to address OP's comment: I've never used this library but according their UdpSocket documentation there are 4 overloads of the Bind() method and every single one of them accepts port in some way. None of them works for you?
like image 127
sbk Avatar answered Oct 13 '22 11:10

sbk


A bidirectional communication link always involves two participants: a server-side and a client-side.

The client expects to communicate to a server on a defined port: that's why on the server-side one must bind() to a socket.

On the client-side, one must open a socket to the server: it doesn't really matter which socket is chosen (except for the need for it to be free).

In other words, don't try to specify a socket on the client-side: the network protocol stack will assign it to your client.

like image 22
jldupont Avatar answered Oct 13 '22 11:10

jldupont