Specify source UDP port when writing datagram
-
Good day, colleagues!
How can I specify source UDP port when writing datagram to remote host? For example, when I write datagram using @writeDatagram( const QByteArray & datagram, const QHostAddress & host, quint16 port )@
I can specify only destination port, but it seems that source port is generated randomly. When sniffering with Wireshark, I saw that source port numbers was for example 52120, 54010, etc.
Can I explicitly specify SOURCE port for UDP datagram? I need it because I work with loopback device and I must know, where should I catch loopback packets.
-
Did you try "QUdpSocket::bind() ":http://doc.qt.nokia.com/4.7/qudpsocket.html#bind?
-
-
Unfortunately, I can't send any packet with the code above. When I remove bind from the code, it works well but the source port is random.
UPDATE: when I wrote like this:
@send_socket_.bind (60000);
send_socket_.writeDatagram (datagram, target_address, 7);@it works well. But is it legal to omit localhost in bind?
-
Of course - otherwise providing the method would not make sense :-)
In your case you just fix the port, but leave the sender's address to the operating system: it chooses that one, that is appropriate for the receiver's address. This could be 127.0.0.1 for a local host recipient and your "real" address for any other.
-
[quote author="usamytch" date="1298994823"]Unfortunately, I can't send any packet with the code above. When I remove bind from the code, it works well but the source port is random.
UPDATE: when I wrote like this:
@send_socket_.bind (60000);
send_socket_.writeDatagram (datagram, target_address, 7);@it works well. But is it legal to omit localhost in bind?[/quote]
In fact you don't want to bind to localhost, but to QHostAddress::Any or so.
-
You send data to a specific port, not from a specific port. The sender port is picked by the OS and it chooses a random, free port for that (the randomness is actually a security feature and not strictly necessary).
To catch packages you bind to some specific port and listen there for incoming packets.
I really do not understand why you need the sender port: With UDP it won't set up a connection and you can not send anything back to the sender port anyway!
If you want to have two parties communicate via UDP, then you need to have both sides listening on a port (each one on a different port of course. The same port number counts as different provided it is on a different host). Then use UDP to send datagrams to the port of the other side.
-
Thank you for the detailed explanation.
I need sender port because I communicate with loopback device. When device receive datagram from me, it send me back datagram copy to the same port it received original datagram from. So, I need to fix sender port because I must know what port to listen to receive feedback.
-
loopback device is just a "virtual network card" that connects your host to itself. It does not change the behavior of applications working with it in any unexpected way.
What you are asking is not possible, are you sure you understood the problem correctly? Is the application you are trying to communicate with actually working? Have you yourself seen any application communicate with it?
-
Loopback that I meant is not virtual network card, it is real "newtork equipment":http://en.wikipedia.org/wiki/Loopback#Telecommunications
As I understand you, it's impossible send and receive datagrams from the same UDP socket. So, I'll try to configure loopback to send me feedback to fixed port, other than the port my packets came from. In this case, as you mentioned, I don't need binding.
As alternative, loopback can send packets to sender_port + n, - in this case I must know sender port and need binding.
-
Are you you need UDP and not TCP?
This whole setup you describe makes no sense with connectionless UDP but could work well with TCP.
-
I use UDP, because I implenent software "RFC 2544":http://www.faqs.org/rfc/rfc2544.txt test.
-
I have only glanced over the document: To me the document seems to be using "ports" as in "things you plug network cables into".
-
[quote author="Tobias Hunger" date="1299000451"]You send data to a specific port, not from a specific port. The sender port is picked by the OS and it chooses a random, free port for that (the randomness is actually a security feature and not strictly necessary).
To catch packages you bind to some specific port and listen there for incoming packets.
[/quote]This is wrong. The UNIX way of selecting the source port is always the same: bind(2) a socket with a port. That's exactly what QUdpSocket::bind does in Qt. OP's error was binding on the localhost interface, therefore the packets sent to another host had the random source port.
[quote]I need sender port because I communicate with loopback device. When device receive datagram from me, it send me back datagram copy to the same port it received original datagram from. So, I need to fix sender port because I must know what port to listen to receive feedback.[/quote]
From this sentence it looks to me that you just need to bind to a (random) source port, which is what every UDP client does in a UDP client/server application. Check out every basic example about UDP, like time/echo servers/clients.
The client will usually perform a bind (on a random port), send the request to the server, and the server replies back to the client using the client's source port as its destination one (he knows about the client source port because it gets it in recvfrom() or any similar call).
The client may also choose to connect() to the server, in order to use send()/write()/read() instead of sendto()/recvfrom(). On older Unixes it also was the only way to be notified about ICMP errors (not Linux, see the SO_BSDCOMPAT socket opt in socket(7)).
-
I have device NetiomUDP, which does the switching of SDI video streams , this device exactly does the same. It receives the commands on UDP packets and returns the UDP packet using the source address. Now in Qt, I am not able to get the source address of the UDP that I sent out. what is the solution.
-
I found my problem
@ bool bret = m_pcUdpSocket->bind(QHostAddress::Any,m_pcUdpSocket->localPort() ,QUdpSocket::ShareAddress);
connect(m_pcUdpSocket, SIGNAL(readyRead()), this, SLOT(SlotReadData()));@@@and
@ qint64 nret = m_pcUdpSocket->writeDatagram((const char*)pqMsg->data(),pqMsg->size(),m_cqHostAddress,m_nPortSocket);@