Unicast with QUdpSocket on Qt - c++

I am trying to send data to a computer with specific ip address on Qt.
If I use Broadcast everything is fine. But when I want to send data to a specific address it does not work. Here is what I have in the transmitter:
udpSocket = new QUdpSocket(this);
QHostAddress myAddress = QHostAddress("192.160.0.1");
udpSocket->writeDatagram((char*)myChar, len, myAddress, 45454);
and at the receiver I have:
udpSocket->bind(45454, QUdpSocket::ShareAddress);
Am I doing something wrong?
Thanks for the help.

After reviewing everything carefully it turned out that I miss typed the receiver ip address. Everything in the above setup is correct and is working.

Related

What are legal addresses for binding a QUdpSocket?

I tried to bind my socket to some random address 10.1.1.1:12001, and got QAbstractSocket::SocketAddressNotAvailableError.
Than i wrote a simple code:
for (int i = 0; i < 256; i++) {
QHostAddress address0(QString::number(i) + ".0.0.1");
quint16 port = 12101;
QUdpSocket* m_socket = new QUdpSocket();
if (m_socket->bind(address0, port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
qDebug() << i;
}
}
Only to learn that IP must start with 127 or 224-239. So it must be Class D address.. But I just didn't find anything in the qt documentation.
Is it a normal behaviour? Is there a possibility to use a global net IP for binding? Or at least use 192.168.x.x as IP of another computer in LAN?
You are not allowed to bind the socket to an arbitrary network IP address. You can only do it with an IP address of one of your network devices or some special IP addresses like 0.0.0.0. By default you always have the 127.0.0.1 but surely you have another network address in your computer.
By the other way if you want to write/read some data over an UDP Socket It's not necessary to bind it to a network address, you can use writeDatagram() or readDatagram() methods of the QUdpSocket class

Qt - QUdpSocket bind failed constantly

I have these 2 lines of code.
I need a socket that just receives data
The first method is working, and I receive date (from the ip/port in the second method)
The second method is always returning false.
I don't understand the difference and can't find the problem.
Any one have any idea how to resolve this or what I'm doing wrong?
udpSocket = new QUdpSocket();
bool result = udpSocket->bind(QHostAddress::Any, 7755);
QHostAddress address("the ip")
udpSocket = new QUdpSocket();
bool result = udpSocket->bind(address , 7755);
In first method, when you bind the socket bind(QHostAddress::Any, 7755) it will listen on all interfaces on your system; thus it will bind successfully knowing that at least one interface is up.
In the second method, when you set the IP Address with QHostAddress address("the ip") you need to make sure that an interface is up with that IP address at your system (use ipconfig on Win / ifconfig on Linux).
Now the constructor will automatically detect from the string passed ("ip address") whether its IPv4 or IPv6.
If you are not specifying a type, then you can construct the address as Any and bind your socket to it:
QString string("192.168.1.1");
QHostAddress address(QHostAddress::Any);
address.setAddress(string);
udpSocket = new QUdpSocket();
bool result = udpSocket->bind(address , 7755);

udp local connection between 2 computers using qt

I have a problem to connect 2 computers by using UDP protocol. As reference I've used broadcast server and broadcast receiver provided by qt (version 5.9). So what's the problem. When I want to check this 2 programs on one computer, they works correct, but when i use them on the different machines, all crashes. Datagrams wasn't received by receiver computer. What am i do wrong? Could anyone answer me.
sender code:
void Sender::broadcastDatagram()
{
statusLabel->setText(tr("Now broadcasting datagram %1").arg(messageNo));
//! [1]
QByteArray datagram = "Broadcast message " + QByteArray::number(messageNo);
udpSocket->writeDatagram(datagram.data(), datagram.size(),
QHostAddress::Broadcast, 45454);
//! [1]
++messageNo;
}
`
and receiver
udpSocket->bind(QHostAddress::Any,45454, QUdpSocket::ShareAddress);
sender ip is 127.0.0.1 ;
receiver ip is 10.0.0.10

get next open tcp port in windows

How is it possible to get next open tcp port on windows
I've searched the web and i came across TcpPortsGatherer written in Qt...
the only problem is that its not available in my current Qt version or it should be used as a plugin
so I'm looking for a way to use TcpPortsGatherer Class
or just use native windows libraries if any is available
Update :
I've Used Sebastian's approach like below to bind the found port to an external binary that I run but it always assign the port 1025 to the executable , how can i fix this ?
QTcpSocket *socket = new QTcpSocket();
qint16 port = 1025;
while(!socket->bind(port, QAbstractSocket::DontShareAddress))
port++;
socket->close();
socket->deleteLater();
Just specify port zero and bind. The system will give you the next available port. No loop required.
You could just try using QTcpSocket::bind(). It will return a bool(true) if port open was successfull.
QTcpSocket *socket = new QTcpSocket();
qint16 port = 1025;
while(!socket->bind(port, QAbstractSocket::DontShareAddress))
{
port++;
}
socket is now bound to port.

Socket Client send using connection accepted by Server

Is it right method client send data using the same connection accepted by server?.
The situation is like this, I have blue tooth server running on my PC and on the other side I have android phone with client and server. From android side the client start connection. I am using blue-tooth chat example from android samples.
And the server-client on android look like
BluetoothSocket socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
And in the PC side I am using Bluez libraries to implement server and client.
The code includes blue tooth receive thread and a main thread, whenever the server accept a connection from android phone I just assign the socket value to a global variable and whenever the client need to send data it send using the same socket ,
Server:-
int GLOBAL_CLIENT;
void* recive_bluetooth_trd(void*)
{
...............................
..............................
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
GLOBAL_CLIENT=client;
while(1){
bytes_read = read(client, buf, sizeof(buf));
....................
...................
}
Client:-
void clinet(char *msg, int length){
........................
int bytes_write=write(GLOBAL_CLIENT,message, length);
..........................
}
My question is, Is it a right method ? The problem is that some times the client send data successfully from PC but not receiving on android side.
The biggest problem I see is that you won't ever leave your while(1) loop, even when the client disconnects. Read will return immediately forever with 0 bytes read (check for a return code of <= 0), trying to signal that the socket is disconnected. Your code will go into a tight infinite loop and use up all the CPU resources it can get its single-threaded hands on.
You need to make sure you ALWAYS check your socket and IO return codes and handle the errors correctly. The error handling for sockets is usually about 3x the actual socket code.
Unless of course the .......... stuff is the important bits. Always tough to tell when people hide code relevant to the question they are asking.
Seems correct to me, but after read you have to NUL ('\0') terminate your buffer if you are treating with strings:
buf[bytes_read] = '\0';