Unable to receive via QUdpSocket multicast.
To be precise, it cannot be received if the Internet is enabled.
However, it may work fine on other PCs. (Some PCs don't work.)
There is no significant difference in those environments.
On Wireshark, I could see the data and on SocketDebugger, I could receive it.
Why is this so strange?
My environment
OS: Windows10
Qt: 5.15.0 MinGW
Peripheral equipment: LUD-U3-AGH
udp.ccp
void Udp::fnUdpSetting(QString localIP,quint16 multicastPort,QString multicastIP)
{
m_pUdpSockRecv = new QUdpSocket(this);
connect(m_pUdpSockRecv, SIGNAL( readyRead() ), this, SLOT( fnUdpRecvData() ));
if( m_pUdpSockRecv->bind( QHostAddress( localIP ) , multicastPort, QUdpSocket::DefaultForPlatform) ){
if( m_pUdpSockRecv->joinMulticastGroup( QHostAddress( multicastIP ) )) {
qDebug() << "Connection Success";
} else {
qDebug() << "Join Error";
}
}
else {
qDebug() << "Bind Error";
}
}
void Udp::fnUdpRecvData()
{
qDebug() << "OK";
}
Related
I want to receive UDP messages using QT. The code I use (see bellow) works well, but the problem is that it only works for one message: after receiving one message, the code still running, but it seems that it doesn't receive anything anymore.
Indeed, after the first message received, the console display qDebug() << "in !";, meaning that it enters into the function, but never received other UDP messages.
I already check, I sure the message is well sent by the UDP server. So the problem must come from here. Any suggestions?
Launching UDP when the class is created:
App::App(QWidget *parent)
: QMainWindow(parent), imageLabel(new QLabel)
, scrollArea(new QScrollArea)
{
.....
StartUDP();
....
}
The UDP initialization:
void App::StartUDP()
{
socket = new QUdpSocket(this);
bool result = socket->bind(QHostAddress::AnyIPv4, 17);
qDebug() << result;
if(result)
{
qDebug() << "PASS";
}
else
{
qDebug() << "FAIL";
}
readyRead();
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()),Qt::QueuedConnection);
}
The function that what for UDP signal:
void App::readyRead()
{
qDebug() << "in !";
QHostAddress sender;
quint16 port;
while (socket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(socket->pendingDatagramSize());
socket->readDatagram(datagram.data(),datagram.size(),&sender,&port);
qDebug() <<"Message From :: " << sender.toString();
qDebug() <<"Port From :: "<< port;
qDebug() <<"Message :: " << datagram;
file_name = datagram;
m_SystemTrayIcon->showMessage(tr("Message"), tr("Nouveau fichier détecté"));
}
}
I am using Qt 4.8 GCC 32bit on xUbuntu 14.04.
I have the following piece of code, a TCP server that I use in order to get some remote commands and send back some answers - via TCP socket:
struct _MyRequest
{
unsigned long Request;
unsigned long Data;
} __attribute__((packed));
struct _MyAnswer
{
unsigned long Error;
unsigned long Filler;
} __attribute__((packed));
_MyRequest request;
_MyAnswer answer;
RemoteCmdServer::RemoteCmdServer(QObject * parent)
: QTcpServer(parent)
{
qDebug() << "Server started";
listen(QHostAddress("172.31.250.110"), 5004);
connect(this, SIGNAL(newConnection()), this, SLOT(processPendingRequest()));
}
void RemoteCmdServer::processPendingRequest()
{
qDebug() << "Process request";
QTcpSocket * clientConnection = nextPendingConnection();
connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
// get the request
int ret = clientConnection->read((char*)&request, sizeof(request));
qDebug() << "READ: " << ret;
if(ret == sizeof(request))
{
// send answer
clientConnection->write((char*)&answer, sizeof(answer));
}
qDebug() << "Disconnecting...";
clientConnection->disconnectFromHost();
}
I am able to write correctly if I comment the if(ret == sizeof(request)) line.
Yet, I can't read from the socket (I always get 0 bytes).
I am 100% sure that the TCP-tool I use to send packets to my app works ok.
Here is the debug output from my app:
Server started
Process request
READ: 0
Disconnecting...
What am I doing wrong? Please advise!
You should wait for the data either in a non-blocking or blocking way. You can use waitForReadyRead to do it in a blocking way.
void RemoteCmdServer::processPendingRequest()
{
qDebug() << "Process request";
QTcpSocket * clientConnection = nextPendingConnection();
connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
if (clientConnection->waitForReadyRead())
{
// get the request
QByteArray message = clientConnection->readAll(); // Read message
qDebug() << "Message:" << QString(message);
}
else
{
qDebug().nospace() << "ERROR: could not receive message (" << qPrintable(clientConnection->errorString()) << ")";
}
qDebug() << "Disconnecting...";
clientConnection->disconnectFromHost();
}
You're trying to read data from the new connection without returning to the Qt event loop -- I don't think that's going to work.
After you've accepted the connect with...
QTcpSocket * clientConnection = nextPendingConnection();
You need to connect to its readyRead signal with something like...
connect(clientConnection, SIGNAL(readyRead()), this, SLOT(my_read_slot()));
Where my_read_slot is the member function that will actually perform the read operation.
I have a server that can handle multiple threads. The server starts and listens, but it is having trouble echoing when an incoming connection is pending.
I am using telnet to open the socket and send data to the server. However, the server only displays that it's listening, but doesn't echo any of the data I type through telnet or signify that there is an incoming connection. I shut off Windows firewall for private networks and still...nothing.
Also tried seeing if the server error string had anything useful to say, but all it is just an empty string.
This is a complete mystery to me and if anyone had anything constructive to note, it'd be much appreciated. Code for the thread and server is below.
server.cpp
#include "myserver.h"
MyServer::MyServer(QObject *parent) :
QTcpServer(parent)
{
}
void MyServer::StartServer()
{
if(!this->listen(QHostAddress::Any,1234))
{
qDebug() << "Could not start server";
}
else
{
qDebug() << "Listening...";
}
}
void MyServer::incomingConnection(int socketDescriptor)
{
qDebug() << socketDescriptor << " Connecting...";
MyThread *thread = new MyThread(socketDescriptor,this);
connect(thread, SIGNAL(finished()),thread, SLOT(deleteLater()));
thread->start();
}
thread.cpp
#include "mythread.h"
MyThread::MyThread(int ID, QObject *parent) :
QThread(parent)
{ this->socketDescriptor = ID;
}
void MyThread::run()
{
qDebug() << socket->errorString();
//thread starts here
qDebug() << socketDescriptor << " Starting thread";
socket = new QTcpSocket();
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
emit error(socket->error());
return;
}
connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);
connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()),Qt::DirectConnection);
qDebug() << socketDescriptor << " Client Connected";
exec();
}
void MyThread::readyRead()
{
QByteArray Data = socket->readAll();
qDebug() << socketDescriptor << " Data in: " << Data;
socket->write(Data);
}
void MyThread::disconnected()
{
qDebug() << socketDescriptor << " Disconnected";
socket->deleteLater();
exit(0);
}
Which version of Qt are you using? In Qt 5, the parameter for the function incomingConnection is of type qintptr and not int. Have a look at the following links:
incomingConnection - Qt 5
Qt 5 - Multithreaded server tutorial
I'm trying to establish bluetooth connection between laptop and Samsung Smart Touch Remote. My issue is that I can't connect socket to device(socket is always in "Host lookup state"):
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Create a discovery agent and connect to its signals
QBluetoothDeviceDiscoveryAgent *discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
connect(discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
this, SLOT(deviceDiscovered(const QBluetoothDeviceInfo&)));
// Start a discovery
discoveryAgent->start();
}
void MainWindow::deviceDiscovered(const QBluetoothDeviceInfo &device)
{
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this);
socket->connectToService(QBluetoothAddress(device.address()),
QBluetoothUuid(QBluetoothUuid::SerialPort));
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)),
this, SLOT(socketError(QBluetoothSocket::SocketError)));
connect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(socketRead()));
connect(socket, SIGNAL(stateChanged(QBluetoothSocket::SocketState)), this, SLOT(socketStateChanged()));
}
void MainWindow::socketRead()
{
QByteArray receivedData = socket->readAll();
QMessageBox msg;
msg.setText(QString(receivedData));
msg.exec();
}
void MainWindow::socketConnected()
{
qDebug() << "Socket connected";
qDebug() << "Local: "
<< socket->localName()
<< socket->localAddress().toString()
<< socket->localPort();
qDebug() << "Peer: "
<< socket->peerName()
<< socket->peerAddress().toString()
<< socket->peerPort();
}
void MainWindow::socketDisconnected()
{
qDebug() << "Socket disconnected";
socket->deleteLater();
}
void MainWindow::socketError(QBluetoothSocket::SocketError error)
{
qDebug() << "Socket error: " << error;
}
void MainWindow::socketStateChanged()
{
int socketState = socket->state();
QMessageBox msg;
if(socketState == QAbstractSocket::UnconnectedState)
{
msg.setText("unconnected");
}
else if(socketState == QAbstractSocket::HostLookupState)
{
msg.setText("host lookup");
}
else if(socketState == QAbstractSocket::ConnectingState )
{
msg.setText("connecting");
}
else if(socketState == QAbstractSocket::ConnectedState)
{
msg.setText("connected");
}
else if(socketState == QAbstractSocket::BoundState)
{
msg.setText("bound");
}
else if(socketState == QAbstractSocket::ClosingState)
{
msg.setText("closing");
}
else if(socketState == QAbstractSocket::ListeningState)
{
msg.setText("listening");
}
msg.exec();
}
Can someone please tell me what I'm doing wrong?
Have you tried to open a COM port on your Laptop which is connected to the Laptop's bluetooth module?
You can go to Bluetooth settings -> Com Ports -> Add a new com port. Then open this Port using hypertermical or Teraterm. Now try to connect from your Android phone...
Hope this works!
I had the samme issue. The fix was to use a port 1 in argument to socket->connectToService(addr, 1).
This tells SDP to use connection as channel via SDP.
I am using QUdpSocket in order to receive data from a server. When i receive data With SFML its working, i can receive data throught SocketUdp but with qt it doesn't work.
void TheClass::Bind()
{
m_sock_receive = new QUdpSocket(this);
if (m_sock_receive->bind(QHostAddress::Any, port))
{
std::cout << "Bind: OK" << std::endl;
connect(m_sock_receive, SIGNAL(readyRead()), this, SLOT(QtReceive()));
}
else
std::cout << "Bind: NOK" << std::endl;
}
void TheClass::QtReceive()
{
std::cout << "Pending data !" << std::endl;
}
I would make the connect before the bind. It's possible that after binding, the readyRead fires before the connect call is completed. If you don't empty the pending datagrams, the readyRead will not fire again.
In order to connect SIGNAL(readyRead()) to any slot, the QUdpSocket must be in a QAbstractSocket::BoundState. Although you call bind before connect, the bind on QUdpSocket makes a non-blocking call, meaning, that the bind might be delayed. To ensure that you connect the SIGNAL(readyRead()) to SLOT(QtReceive()) after the bind has finished and the QUdpSocket is in a bound state, do the following:
void TheClass::Bind()
{
m_sock_receive = new QUdpSocket(this);
connect(m_sock_receive, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
if (m_sock_receive->bind(QHostAddress::Any, port))
{
std::cout << "Bind: OK" << std::endl;
}
else
std::cout << "Bind: NOK" << std::endl;
}
void TheClass::QtReceive()
{
std::cout << "Pending data !" << std::endl;
}
void TheClass::onSocketStateChange (QAbstractSocket::SocketState state) {
if ( state == QAbstractSocket::BoundState ) {
connect(m_sock_receive, SIGNAL(readyRead()), this, SLOT(QtReceive()));
}
}