Can not start a QTcp Server - c++

I'm having a weird error. I'm trying to establish a connection to a server but the Server doesn't seem to start. Here's the Server.cpp:
Server::Server (QObject *parent) :
QTcpServer(parent)
{
}
void Server::start()
{
QHostAddress pHost;
pHost.setAddress("192.168.10.10"); //Setting the Address of the Server to the Address of the target system
QString printAddress;
printAddress = pHost.toString();
printf(QString("starting Host under " + printAddress + " \n").toStdString().c_str());
if (this->listen(pHost, 8016))
{
printf(QString("Server started and Listening \n").toStdString().c_str());
}
else
{
printf("Server could not be started \n");
}
}
In my main.cpp I instantiate the Server and call the method start.
Server pServer;
pServer.start();
this->listen(pHost, 8016) seems to be returning false because i get "Server could not be started" printed. What am I doing wrong? Why does the Server not start?
By the Way the Address 192.168.10.10 is the Address of another Computer in the local Network. Maybe that's why I'm getting an Error ?
I'm trying to establish a connection to that Device.
Any Help is highly appreciated !! Thank you !!

Related

UDP Packet can be seen on wireshark, not seen from output of code

I am trying to receive packet from UDP-connected infrared camera. (FLIR Lepton 2.5) And I'm trying to run my codes on Windows 10, Qt Creator 4.5, Qt 5.9.
As you can see on the capture below, my UDP-connected infrared camera sends UDP packets.
And here's my code:
// myudp.cpp
#include "myudp.h"
#include <QNetworkProxy>
MyUDP::MyUDP(QObject *parent) :
QObject(parent)
{
// create a QUDP socket
socket = new QUdpSocket(this);
socket_cam = new QUdpSocket(this);
cam_address = QHostAddress("192.168.10.197");
cam_port = 32197;
connect(socket, SIGNAL(connected()), this, SLOT(readNwrite()));
socket->connectToHost(cam_address, cam_port, QIODevice::ReadWrite);
if (socket->waitForConnected(2000))
qDebug("Connected!");
else
qDebug("Cannot be connected..");
qDebug() << socket->state();
// seems to be connected...
}
void MyUDP::readNwrite()
{
QByteArray data;
qint64 resize_size = socket->pendingDatagramSize();
//socket have NO size(resize_size == -1, ERROR!)
if(resize_size != -1)
{
qDebug() << "data was resized properly; size: "<<resize_size;
data.resize(socket->pendingDatagramSize());
}
else
qDebug() << "data could not be resized(error)";
qint64 det_num;
det_num = socket->readDatagram(data.data(), 964, &cam_address, &cam_port);
qDebug() << "Can receive data(returns -1 if NO): "<<det_num;
//this returns nothing, too!
qDebug() << "Data is here: " << data.data();
}
Here's my code implementation result:
When signal is connected(), data could not be resized(error)
Can receive data(returns -1 if NO): -1
Data is here:
Connected!
QAbstractSocket::ConnectedState
When signal is readyRead(), Connected!
QAbstractSocket::ConnectedState data was resized properly; size: 0
Can receive data(returns -1 if NO): -1
Data is here:
readyRead signal sometimes seems NOT emitted as expected.
But it is obvious that any data is NOT being sent.
I've tried to find examples which are related to UDP network with a remote network. But there were few of them.
According to some threads, people recommended not to use connectToHost function on UDP network. However, I don't know how to make an approach to remote network without using connectToHost.
I want to know how I should correct my code to get packet from a remote network. Any advice will be very grateful for me because I'm a newbie to UDP network, and Qt.

Can a TCP/IP client connect to an unreachable IP?

I've been searching for ages for my problem and I probably fell 20 times on stackoverflow without finding anything.
Here's my thing : I'm trying to develop a simple TCP/IP client in C++ (I've followed the well written Beej's Guide) that is supposed to communicate with a python TCP/IP server.
My code is (in a function) :
memset(&m_hints, 0, sizeof m_hints);
m_hints.ai_family=AF_UNSPEC;
m_hints.ai_socktype=SOCK_STREAM;
m_portnbrstring=to_string(m_portnbr);
if ((m_getaddrinfostatus=getaddrinfo(m_serverIP,(const char*) m_portnbrstring.c_str(), &m_hints, &m_servinfo))!=0)
{
char tempstrerror[100];
strcpy(tempstrerror,"getaddrinfo in TCPStartClient: ");
strcat(tempstrerror,gai_strerror(m_getaddrinfostatus));
ExitAndDisplayMessage(tempstrerror);
}
for(m_plist=m_servinfo; m_plist!=NULL; m_plist=m_plist->ai_next)
{
if ((m_sockfd=socket(m_plist->ai_family, m_plist->ai_socktype, m_plist->ai_protocol))==-1)
{
perror("Something went wrong when creating TCP socket");
continue;
}
break;
if (connect(m_sockfd, m_plist->ai_addr, m_plist->ai_addrlen)==-1)
{
close(m_sockfd);
perror("Something went wrong when connecting to TCP socket");
continue;
}
break;
}
if (m_plist==NULL) ExitAndDisplayMessage("getaddrinfo in TCPStartClient: failed to connect");
char tempaddr[INET6_ADDRSTRLEN];
inet_ntop(m_plist->ai_family,get_in_addr((struct sockaddr *)m_plist->ai_addr),tempaddr, sizeof tempaddr);
cout << "TCPClient started at IP " << tempaddr << " on port " << ntohs(get_in_port((struct sockaddr *)m_plist->ai_addr)) << endl;
The definitions are
int m_sockfd;
char *m_serverIP;
struct addrinfo m_hints;
struct addrinfo *m_servinfo;
struct addrinfo *m_plist;
Until here, everything looks fine but the connect function keeps sending 0 (no error) even if the IP I specify is unreachable. Basically, connect() works even if the server is down or if a test with a random IP (I tested with fping to be unreachable).
Does anyone have an idea of what's happening ? I'd be glad if someone could kick me out of this.
"Can a TCP/IP client connect to an unreachable IP?" - No. Obviously not.
If whatever you are using to establish a connection reports a successful connection of a TCP socket to an unreachable IP, then whatever you are using is broken (or you are using it wrong (probably the most likely situation) or the IP is in fact reachable).

Bad Request, Your browser sent a request that this server could not understand - Qt Websocket Server

I have two questions about this issue.
First of all I'm trying to get the following code working
socket = new QTcpSocket(this);
// I'm a little confused as to why we're connecting on port 80
// when my goal is to listen just on port 3000. Shouldn't I just
// need to connect straight to port 3000?
socket->connectToHost("localhost", 80);
if (socket->waitForConnected(3000))
{
qDebug() << "Connected!";
// send
socket->write("hello server\r\n\r\n\r\n\r\n");
socket->waitForBytesWritten(1000);
socket->waitForReadyRead(3000);
qDebug() << "Reading: " << socket->bytesAvailable();
qDebug() << socket->readAll();
socket->close();
}
else
{
qDebug() << "Not connected!";
}
But this is the error that I get:
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>400 Bad Request</title>\n</head><body>\n<h1>Bad `Request</h1>\n<p>Your browser sent a request that this server could not understand.<br />\n</p>\n<hr>\n<address>Apache/2.4.18 (Ubuntu) Server at 127.0.1.1 Port 80</address>\n</body></html>\n"`
Has anyone got any ideas about this?
Second question is: I'm trying to get a c++/Qt server working similar to a node js server. So I'm wanting to be able to access the connection requests in the browser. So when someone connects to site:3000 I will be able to catch the request and display some content. Can it be achieved with a QTcpSocket server? If so then how could I implement something like :
// I know this isn't valid c++, Just to give an idea of what I'm trying to achieve
socket.on(Request $request) {
if ($request.method() == 'GET') {
}
}
If this is achievable is there much speed gains in comparison to doing this in nodejs?
I'm personally trying to avoid js as much as possible.
if i comment the code then I can get a running program but when I try to connect on port 8000 from the browser nothing happens (just a 404 error)
updated answer:
header file:
#ifndef SOCKETTEST_H
#define SOCKETTEST_H
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
class SocketTest : public QTcpServer
{
public:
SocketTest(QObject *parent);
private:
QTcpSocket *client;
public slots:
void startServer(int port);
void readyToRead(void);
void incomingConnection(int socket);
};
#endif // SOCKETTEST_H
.cpp file
#include "sockettest.h"
SocketTest::SocketTest(QObject *parent) :
QTcpServer(parent)
{
this->startServer(8000);
}
void SocketTest::startServer(int port)
{
bool success = listen(QHostAddress::Any, port); // this starts the server listening on your port
// handle errors
}
void SocketTest::incomingConnection(int socket)
{
// a client has made a connection to your server
QTcpSocket *client = new QTcpSocket(this);
//client->setSocketDescription(socket);
// these two lines are important, they will direct traffic from the client
// socket to your handlers in this object
connect(client, SIGNAL(readyRead()), this, SLOT(readToRead()));
connect(client, SIGNAL(disconnect()), this, SLOT(disconnected()));
}
void SocketTest::readyToRead(void)
{
QTcpSocket *client = (QTcpSocket*)sender();
qDebug() << "Just got a connection";
// you can process requests differently here. this example
// assumes that you have line breaks in text requests
while (client->canReadLine())
{
QString aLine = QString::fromUtf8(client->readLine()).trimmed();
// Process your request here, parse the text etc
}
}
// this gives me the following error
// /user_data/projects/qt/QtServer/sockettest.cpp:47: error: no ‘void
// SocketTest::disconnected()’ member function declared in class ‘SocketTest’
void SocketTest::disconnected()
^
void SocketTest::disconnected()
{
// jsut a qu, wont all these * vars lead to a memory leak? and shouldn't I be using a var Qtc... *client; in the header file?
QTcpSocket *client = (QTcpSocket*)sender();
// clean up a disconnected user
}
Here with waitForConnected, you are connecting on port 80, and waiting 3000ms maximum for the "connected state", i.e. not connecting on port 3000 at all. This is the blocking way of waiting for a connection to be established, instead of connecting to the QTcpSocket::connected signal.
Like Yuriy pointed out, QNetworkAccessManager is way more convenient to handle HTTP requests as a client. As in your example, you created a TCP client, and not a server
Yes you can build an web server with Qt, it's a bit painfull from scratch (QTcpServer class), but several projects make it a bit easier: QHttpServer, QtWebApp
If performance is your goal, I doubt you can achieve something significantly better (or just "better") without spending a lot of time on it. Namely to be able to handle a large number of request simultaneously in a fast way, a basic implementation will not be enough.
You should subclass QTCPServer. Set it up to listen on the port you want. This object will then get the requests and you can parse them and respond to them.
Something like this (partial code);
#include <QTcpServer>
#include <QTcpSocket>
class mySuperNodeLikeServer : public QTcpServer
{
mySuperNodeLikeServer(QObject *parent);
void startServer(int port);
void readyToRead(void);
void incomingConnection(int socket);
}
// in your .cpp file
void mySuperNodeLikeServer::startServer(int port)
{
bool success = listen(QHostAddress::Any, port); // this starts the server listening on your port
// handle errors
}
void mySuperNodeLikeServer::incomingConnection(int socket)
{
// a client has made a connection to your server
QTcpSocket *client = new QTcpSocket(this);
client->setSocketDescription(socket);
// these two lines are important, they will direct traffic from the client
// socket to your handlers in this object
connect(client, SIGNAL(readyRead()), this, SLOT(readToRead()));
connect(client, SIGNAL(disconnect()), this, SLOT(disconnected()));
}
void mySuperNodeLikeServer::readyToRead(void)
{
QTcpSocket *client = (QTcpSocket*)sender();
// you can process requests differently here. this example
// assumes that you have line breaks in text requests
while (client->canReadLine())
{
QString aLine = QString::fromUtf8(client->readLine()).trimmed();
// Process your request here, parse the text etc
}
}
void mySuperNodeLikeServer::disconnected()
{
QTcpSocket *client = (QTcpSocket*)sender();
// clean up a disconnected user
}

Qt, send UDP through VPN(Hamachi)

I`m writing application, which send voice from one computer to other. I have simple implementation of "sender"
VoiceSender::VoiceSender(QAudioFormat &format, QString ip){
input = new QAudioInput(format);
QUdpSocket* socket = new QUdpSocket();
socket->connectToHost(ip, 14433);
input->start(socket);
}
Just get all data from mic and send it as UDP to specified IP.
In the other side I have program, which get all data received by UDP, and play it by audio system
Interlocutor::Interlocutor(QAudioFormat &format){
socket = new QUdpSocket();
socket->bind(QHostAddress::Any, 14433);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(format))
format = info.nearestFormat(format);
output = new QAudioOutput(format);
device = output->start();
connect(socket, SIGNAL(readyRead()), this, SLOT(playData()));
}
void Interlocutor::playData()
{
qDebug() << QDateTime::currentDateTime();
while (socket->hasPendingDatagrams())
{
QByteArray data;
data.resize(socket->pendingDatagramSize());
socket->readDatagram(data.data(), data.size());
device->write(data.data(), data.size());
}
}
If both computers locating in the local network this works well, i can transfer my voice between computers. I tried to run it in the VPN. For it I run Hamachi in both computers, and got nothing. Slot playData() is never called. I run Wireshark and seen that computer get UDP packages, but Qt doesnt. What should I do to fix it.
Thanks.
You should check the result of the QUdpSocket::bind function.
bool QUdpSocket::bind ( const QHostAddress & address, quint16 port )
On success, the functions returns true and the socket enters
BoundState; otherwise it returns false.
if (!socket->bind(QHostAddress::Any, 14433))
{
QMessageBox::warning(0, "Error", "Binding Failed");
}
If binding is failed check if firewall is not blocking you or this port is not used by another application.

Tcp accept fails after first connection after 1 hour

I have written C++ client server application and the server is crashing.
The scenario
Start server
1 hour later (not before) Client connect
Then the Server which is waiting in accept returns -1 with errno "Too many open files".
Nothing else special is running on the machine which led me to believe that accept is opening many file descriptors while waiting.
Is that true?
How can I fix this so the client could connect anytime?
the relevant server code:
int sockClient;
while (true) {
sockaddr_in* clientSockAddr = new sockaddr_in();
socklen_t clientSockAddrLen = sizeof(sockaddr_in);
sockClient = accept(sockServer, (sockaddr *) clientSockAddr,
&clientSockAddrLen);
if(sockClient == -1 ){
std::ostringstream s;
s << "TCP Server: accept connection error." << std::strerror(errno);
throw runtime_error(s.str());
}
connection->communicate(sockClient, clientSockAddr, clientSockAddrLen);
}
You have a file descriptor leak somewhere. Possibly you aren't closing accepted sockets when you've finished with them, or else it's on a file somewhere.