telnet client not connecting -- to QTCPserver - qt

Why i am not able to connect to a server running on my localhost using telnet client ?
I am using windows-7 & telnet client is turned on in control panel.
Please suggest how to make it working ?
#define SERVER_PORT 5000
Tcp server is created in the tcpserver object :---
tcpserverobject::tcpserverobject(QObject *parent) :
QObject(parent), tcpServer(0)
{
tcpServer = new QTcpServer;
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(on_newConnection()));
}
// Common slot for the tcpserver - thread
void tcpserverobject::dowork()
{
if (!tcpServer->listen(QHostAddress::LocalHost, SERVER_PORT )) {
qDebug() << "\n returning from server listning error .. !!! ";
return;
}
qDebug() << "\n server listning";
//while(1)
while(!m_bQuit)
{
}
}
Server new connection code :---
void tcpserverobject::on_newConnection()
{
QByteArray block;
block.append(" \n Hello from server .. !!!") ;
QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
connect(clientConnection, SIGNAL(disconnected()),
clientConnection, SLOT(deleteLater()));
// Create new thread for this .. client request ..!!
qDebug() << "\n New connection request ..!!!";
qDebug() << "\n New client from:" << clientConnection->peerAddress().toString();
clientConnection->write(block);
clientConnection->flush();
clientConnection->disconnectFromHost();
qDebug() << "\n New connection request closed ..!!!";
}
Now i enter command in telnet :----
C:\Users\Admin> telnet
Welcome to Microsoft Telnet Client
Escape Character is 'CTRL+]'
Microsoft Telnet> open localhost 5000
Connecting To localhost...
I am able to make my server go in listen mode, as following statement is printed :--
qDebug() << "\n server listning";
But why telnet client is not able to connect to the server running on localhost & PORT = 5000 ?

In the function do work, you have this code: -
//while(1)
while(!m_bQuit)
{
}
This is going to stop the current thread from processing messages. If you want to be able to stop the server, have a slot, in the tcpserverobject class, which will close the connection to the QTcpServer when it receives a signal.

Related

Server Sent Events (SSE) with Qt

I already saw several libraries for Server Sent Events, unfortunately, not for Qt. I also looked at the specification of SSE (just plain HTTP) and it seems that implementing SSE in Qt would require to:
Use QNetworkAccessManager in streaming mode (download)
Accept the content type header of SSE: application/events-stream
Reconnect when the connection is lost or closed
Attach a slot to the QNAM when new bytes are received (check for data : {...})
I'm not sure if it's so "easy"? Did I miss something?
I created a small demo with Qt and Server Sent Events.
The demo connects to a given EventSource URL (first argument) and prints every event to the command line.
Qt supports SSE out of the box since SSE is pure HTTP with a reconnection layer on top of it.
Prepare the request: set the text/event-stream accept header, allow redirects, disable the cache.
QNetworkRequest Network::Manager::prepareRequest(const QUrl &url)
{
QNetworkRequest request(url);
request.setRawHeader(QByteArray("Accept"), QByteArray(ACCEPT_HEADER));
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); // Events shouldn't be cached
return request;
}
Connect the readyRead signal to a slot.
void Network::Manager::getResource(const QUrl &url)
{
qDebug() << "GET resource:" << url;
QNetworkRequest request = this->prepareRequest(url);
m_reply = this->QNAM()->get(request);
connect(m_reply, SIGNAL(readyRead()), this, SLOT(streamReceived()));
}
Every time a new event is received by the QNetworkAccessManager, you can read it using readAll. We reset the retries counter after every successful event.
void Network::Manager::streamReceived()
{
qDebug() << "Received event from stream";
qDebug() << QString(m_reply->readAll()).simplified().replace("data: ", "");
qDebug() << "-----------------------------------------------------";
m_retries = 0;
}
In case we lost the connection or the connection times out, the finished() signal is triggered of the QNetworkAccessManager. We try to reconnect to the event source (We connected this slot to the signal when we created our QNetworkAccessManager instance):
void Network::Manager::streamFinished(QNetworkReply *reply)
{
qDebug() << "Stream finished:" << reply->url();
qDebug() << "Reconnecting...";
if(m_retries < MAX_RETRIES) {
m_retries++;
this->getResource(reply->url());
}
else {
qCritical() << "Unable to reconnect, max retries reached";
}
}
You can find the demo here: https://github.com/DylanVanAssche/Qt-Server-Sent-Events-Demo

How set QTcpServer listening alone on port using Win7

I use a QTcpServer that should listen alone on port. Language is c++ with Qt 5.9. The application must run under Win and Linux using MingW. The listen method from QTcpServer uses standard parameter for socket options. For Win10, Linux these options are set default to single usage of the listening port so listening works fine. Unfortunatly opposite to that Win7 offers shared usage which i must avoid.
I figured out that the QAbstractSocket class let me create a socket with the BindFlag::DontShareAddress. I can forward the socketdescriptor to the QTcpServer. Then the method listen fails (isn't listening) by stating: QTcpServer::listen() called when already listening. I check the ports status by using netstat.
My code sample is below:
bool TcpServer::init(QString ipAddress, quint16 port, Command::RoutingProperty clientSocketKind, QString interfaceName)
{
if (mServerIsInit == true) // only 1 server instance
{
return false;
mServer = new (std::nothrow) QTcpServer();
if (mServer == nullptr)
{
return false;
}
mClientSocketKind = clientSocketKind;
mInterfaceName = interfaceName;
// tries to set socket properties to a non sharing port
QTcpSocket tsocket;
if (!tsocket.bind(QHostAddress(ipAddress), port, QAbstractSocket::BindFlag::DontShareAddress))
{
qDebug() << "Socket bind fails";
}
else
{
qDebug() << "Socket bind success";
}
sd = tsocket.socketDescriptor(); // valid socket descriptor
if (!mServer->setSocketDescriptor(sd))
{
qDebug() << "SocketDescriptor fails";
}
sd = mServer->socketDescriptor();
qDebug() << "Socketdescriptor Server " << sd;
//end tries to set socket properties to a non sharing port
if (mServer->listen(QHostAddress(ipAddress), port)) // fails with message ... is always listening
// if (mServer->mServer->isListening()) // is not listening tells netstat
{
qDebug() << "Server status for listening ok: " << mServer->isListening();
qDebug() << "Server listen on " << mServer->serverAddress() << ":" << mServer->serverPort();
connect(mServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
connect(mServer, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(socketErr(QAbstractSocket::SocketError)));
mServerIsInit = true;
return true;
}
else
{
qDebug() << "Server status for listening fail" << mServer->isListening();
delete mServer;
mServer = nullptr;
return false;
}
}
Thanks for any idea how to set the socket options for a exclusive usage of the listening port.
Martin
As per the comment, you will probably need to call listen explicitly on the socket descriptor before calling QTcpServer::setSocketDescriptor.
The following code is untested but should give you some idea...
if (!tsocket.bind(QHostAddress(ipAddress), port, QAbstractSocket::BindFlag::DontShareAddress))
{
qDebug() << "Socket bind fails";
}
else
{
qDebug() << "Socket bind success";
}
sd = tsocket.socketDescriptor(); // valid socket descriptor
/*
* Now make an explicit call to `listen' so that the socket descriptor
* can be passed to QTcpSocket::setSocketDescriptoy.
*/
if (listen(sd, SOMAXCONN) == SOCKET_ERROR)
{
printf("Listen failed with error: %ld\n", WSAGetLastError());
closesocket(sd);
WSACleanup();
/*
* Handle error.
*/
}
if (!mServer->setSocketDescriptor(sd))
{
qDebug() << "SocketDescriptor fails";
}
As an aside, note that you need to be a bit more careful with error handling -- simply call qDebug and continuing will come back to bite you at some point.

QT QTcpServer listen

i have a question about QT QTcpServer server->listen(QHostAddress, qint16). I have problems with the address.
I tried with QHostAddress("127.0.0.1"), and that worked. I tried with QHostAddress::Any, and that failed (error 10, not supported). I tried with QHostAddress::AnyIPv4, and that failed (same error). I tried with QHostAddress("0.0.0.0"), and that failed, with same error. I tried with the address of the interface, that worked.
NotificationServer::NotificationServer(QObject *parent) : QObject(parent) {
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
if (!server->listen(QHostAddress::Any, port)) {
qDebug() << "Server could not start." << server->serverError();
server = nullptr;
} else {
qDebug() << "Server started.";
}
}
It seems, that it is not possible making the QTcpServer listen on all interfaces. OS is Linux XUbuntu. How can i make the server listen at all interfaces?

Qt5 WebSockets test app not connecting to test service

I wanted to open a qt websocket to the test service in ws://echo.websocket.org but I got the error QAbstractSocket::RemoteHostClosedError
I am connecting the signal error(QAbstractSocket::SocketError socketError) to a slot in my code in order to read the error number then look for it in here
My code looks like this
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Controller w;
w.initializeWebSocket("ws://echo.websocket.org", true);
w.show();
return a.exec();
}
Controller::Controller(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
void Controller::initializeWebSocket(QString url, bool debug)
{
m_webSocketURL = url;
m_webSocketDebug = debug;
if(m_webSocketDebug)
std::cout << "WebSocket server: " << m_webSocketURL.toStdString() << std::endl;
QObject::connect(&m_webSocket, SIGNAL(connected()), this, SLOT(onConnected()));
QObject::connect(&m_webSocket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
QObject::connect(&m_webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
QObject::connect(&m_webSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(onTextMessageReceived(QString)));
m_webSocket.open(QUrl(m_webSocketURL));
}
void Controller::onConnected()
{
if (m_webSocketDebug)
std::cout << "WebSocket connected" << std::endl;
m_webSocket.sendTextMessage(QStringLiteral("Rock it with HTML5 WebSocket"));
}
void Controller::onDisconnected()
{
if (m_webSocketDebug)
std::cout << "WebSocket disconnected" << std::endl;
}
void Controller::onError(QAbstractSocket::SocketError error)
{
std::cout << error << std::endl;
}
void Controller::onTextMessageReceived(QString message)
{
if (m_webSocketDebug)
std::cout << "Message received:" << message.toStdString() << std::endl;
m_webSocket.close();
}
Im new to websockets so I have no idea where could the problem be. Can anyone give advise?
Opening websocket at "ws://echo.websocket.org" works for me just fine.
These handlers are sufficient in my project:
connect(&webSocket, SIGNAL(connected()), this, SLOT(onConnected()));
connect(&webSocket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
connect(&webSocket, SIGNAL(textMessageReceived(const QString&)), this, SLOT(onTextMessageReceived(const QString&)));
I also just realized that I don't connect error() signal yet the program code is quite reliable for more than a year already and in case of disconnect there is a connection restore kick in. Maybe I should connect error() signal as well for infrequent strange cases.
The error QAbstractSocket::RemoteHostClosedError can be just a correct thing to get. Try to get the echo within reasonable time. The websocket farm we use in our project is holding the connection for up to 50 minutes so we do ping-pong between the client and the server to keep the connection live before this period expires.
// you can try that immediately after opening the web socket and also using some QTimer
m_webSocket.sendTextMessage("Pong!");
Try that and see the text reply as long as you are playing some public echo service.
Well, I verified your code and it seems to work fine. The error you give indicates a host related issue. It may be due to firewall, isp or other blocks/issues.
WebSocket server: ws://echo.websocket.org
WebSocket connected
Message received:Rock it with HTML5 WebSocket
WebSocket disconnected
I do like to point out that it's preferred to keep a pointer to a QWebSocket 'object'. It's very convenient to declare m_webSocket as QWebSocket *, and add m_webSocket = new QWebSocket(this). It's good practice to treat objects as objects. You don't want to accidentally try to 'copy' an QWebSocket directly. Also, due to the internals of Qt, you may eventually run into problems if this "Controller" object is destroyed while the QWebSocket is still attached to other objects (although I think Qt is prepared for it).

QTcpSocket problem

Writing a chat using Qt. Got a problem. My client's QTcpSocket remains in connecting state, but the server emits newConnection() signal. Network session is not required. Why is that? Here is some code:
ChatClient::ChatClient(QObject *parent)
: QObject(parent) {
tcpSocket = new QTcpSocket(this);
QNetworkConfigurationManager manager;
if (QNetworkConfigurationManager::NetworkSessionRequired
& manager.capabilities()) {
qDebug() << "Network session required";
}
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(error(QAbstractSocket::SocketError)));
connect(tcpSocket, SIGNAL(connected()),
this, SLOT(requestForID()));
connect(tcpSocket, SIGNAL(readyRead()),
this, SLOT(receiveMessage()));
tcpSocket->connectToHost("192.168.0.100", PORT);
}
void ChatClient::requestForID() {
qDebug() << "Connected, requesting for ID";
QByteArray segment;
QDataStream out(&segment, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_7);
out << (quint16)0 << ID;
out.device()->seek(0);
out << (quint16)(segment.size() - sizeof(quint16));
tcpSocket->write(segment);
}
requestForID() is never being executed
ChatServer::ChatServer(QObject *parent)
: QObject(parent) {
tcpServer = new QTcpServer(this);
if (!tcpServer->listen(QHostAddress::Any, PORT)) {
qDebug() << "Unable to start the server"
<< tcpServer->errorString();
}
qDebug() << "Server port" << tcpServer->serverPort();
connect(tcpServer, SIGNAL(newConnection()),
this, SLOT(processConnection()));
}
void ChatServer::processConnection() {
qDebug() << "Incoming connection";
QTcpSocket *clientSocket = tcpServer->nextPendingConnection();
/*connect(clientSocket, SIGNAL(readyRead()),
this, SLOT(readData()));
readData(clientSocket);
connect(clientSocket, SIGNAL(disconnected()),
clientSocket, SLOT(deleteLater()));*/
QByteArray segment;
QDataStream out(&segment, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_7);
out << (quint16)0 << (quint16)Message
<< "Successfully connected";
out.device()->seek(0);
out << (quint16)(segment.size() - sizeof(quint16));
clientSocket->write(segment);
clientSocket->disconnectFromHost();
}
server displays incoming connection and the client does not emit connected remaining in connecting state, doesnt receive server message as well...
Any ideas?
I had the same problem and I found the reason and a solution.
connectToHost may not be called in the contstructor of the main window directly. Why?
The reason is, that the main message loop is not running yet at this time. Internally QAbstractSocketPrivate::fetchConnectionParameters() gets never called and Qt Socket Timeout Timer thinks connection is never established.
The solution is either to call it "delayed" like in
QMetaObject::invokeMethod(this, "OnDelayedConnect", Qt::QueuedConnection);
Or to call waitForConnected() after connectToHost

Resources