I tried to run simple client-server app in QT. Problem is with "connect" on server side - newConnection slot isn't executed and exception appears (like in title).
***************myserver.cpp***********
#include "myserver.h"
myserver::myserver(){}
myserver::~myserver(){}
void myserver::startServer()
{
qDebug()<<"Starting startServer()";
tcpServer = new QTcpServer(this);
if (this->listen(QHostAddress::Any,1000))
{
qDebug()<<"Listening";
}
else
{
qDebug()<<"Not listening";
}
}
void myserver::incomingConnection(int socketDescriptor)
{
qDebug()<<"incomingConnection() started";
socket=new QTcpSocket(this);
socket->setSocketDescriptor(socketDescriptor);
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
qDebug()<<socketDescriptor<<"Client connected";
}
void myserver::onNewConnection()
{
qDebug()<<"onNewConnection() started";
}
**********myserver.h**************
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
class myserver: public QTcpServer
{
Q_OBJECT
public:
myserver();
~myserver();
QTcpSocket* socket;
QTcpServer *tcpServer=nullptr;
public slots:
void startServer();
void incomingConnection(int socketDescriptor);
void onNewConnection();
};
#endif // MYSERVER_H
***********testClient.cpp**************
#include "myclient.h"
#include "ui_myclient.h"
myclient::myclient(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::myclient)
{
ui->setupUi(this);
socket=new QTcpSocket(this);
connect(socket,SIGNAL(connected()),this,SLOT(socketMap()));
}
myclient::~myclient()
{
delete ui;
}
void myclient::on_pushButton_clicked()
{
socket->connectToHost("127.0.0.1",1000);
if(socket->isOpen())
{
qDebug()<<"Connected!";
}
else {
qDebug()<<"Not connected";
}
}
void myclient::socketMap()
{
qDebug()<<"socketMap() started";
}
I expected onNewConnection() being called when client connects. Also I have checked client side and connection is confirmed.
This is console output on server:
Starting startServer()
Listening
incomingConnection() started
948 Client connected
Related
As the title says, i have created a client which receives data from my server. So far i can print it in my console, but i would like to work with it. (The data that the client recevies is from my Smartphones accelerometer sensor)
My Socket.h class:
#ifndef SOCKETTEST_H
#define SOCKETTEST_H
#include <QObject>
#include <QDebug>
#include <QTcpSocket>
#include <QAbstractSocket>
class SocketTest : public QObject
{
Q_OBJECT
public:
explicit SocketTest(QObject *parent = nullptr);
void Test();
signals:
public slots:
void connected();
void disconnected();
void bytesWritten( qint64 bytes);
void readyRead();
private:
QTcpSocket *socket;
};
#endif // SOCKETTEST_H
and socket.cpp :
#include "sockettest.h"
SocketTest::SocketTest(QObject *parent)
: QObject{parent}
{
}
void SocketTest::Test()
{
socket = new QTcpSocket(this);
connect (socket, SIGNAL(connected()),this, SLOT(connected()));
connect (socket, SIGNAL(disconnected()),this, SLOT(disconnected()));
connect (socket, SIGNAL(readyRead()),this, SLOT(readyRead()));
connect (socket, SIGNAL(bytesWritten(qint64)),this, SLOT(bytesWritten(qint64)));
qDebug() <<"Connecting...";
socket->connectToHost("MY IP", PORT);
if(!socket->waitForConnected(2000))
{
qDebug() <<"Error" << socket->errorString();
}
}
void SocketTest::connected()
{
qDebug() <<"Connected!";
socket->write("\r\n\r\n\r\n\r\n");
}
void SocketTest::disconnected()
{
qDebug() <<"Disconnected!";
}
void SocketTest::bytesWritten(qint64 bytes)
{
qDebug() <<"We wrote: " <<bytes;
}
void SocketTest::readyRead()
{
qDebug() << socket->readAll();
}
typically what i want to create, in another class, is an if statment which moves an Object based on the sent data :
if( received_data == 5 ){
this->setX(this->x()+1);
}
I'm trying to send an audio stream from a microphone via TCP in a thread other than the main thread. Therefore I've set up a server an I'm listening for incoming connections. Once a client connects, I want to send it the audio stream. I've read the Qt Documentation about QTcpServer, Multithreading, and QtMultimedia. I've also looked at this website for example code about multithreading and TCP servers in Qt. The problem is this message that I get during runtime:
QObject: Cannot create children for a parent that is in a different thread. (Parent is QNativeSocketEngine(0xae802a78), parent's thread is MyThread1(0x1856d28), current thread is QThread(0x1838aa0)
this is my code:
in file myserver.h
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QtNetwork>
#include <QTcpServer>
#include <mythread.h>
#include <QtMultimediaKit/QAudioFormat>
#include <QtMultimediaKit/QAudioInput>
#include <QtMultimediaKit/QAudioDeviceInfo>
class MyServer : public QTcpServer
{
Q_OBJECT
public:
explicit MyServer(QObject *parent = 0);
void startServer();
signals:
public slots:
protected:
void incomingConnection(int socketDescriptor);
private:
QAudioInput *audioInput;
};
#endif // MYSERVER_H
in file myserver.cpp
#include "myserver.h"
MyServer::MyServer(QObject *parent) :
QTcpServer(parent)
{
}
void MyServer::startServer()
{
int port = 12345;
QString ipAddress;
QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
for (int i = 0; i < ipAddressesList.size(); ++i)
{
if (ipAddressesList.at(i) != QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address())
{
ipAddress = ipAddressesList.at(i).toString();
break;
}
}
if(!this->listen( QHostAddress(ipAddress),port ) )
{
qDebug() << "Could not start server";
}
else
{
qDebug() << "The server is running on\n\nIP: "<< ipAddress;
qDebug() << "\nport: " << this->serverPort() << "\n\n";
}
}
void MyServer::incomingConnection(int socketDescriptor)
{
qDebug() << socketDescriptor << " Connecting...";
QAudioFormat format;
format.setSampleRate(44100);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(format))
{
qWarning()<<"default format not supported try to use nearest";
format = info.nearestFormat(format);
}
audioInput = new QAudioInput(format, this);
MyThread1 *thread = new MyThread1(socketDescriptor,audioInput, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
in file mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QDebug>
#include <QtMultimediaKit/QAudioInput>
class MyThread1 : public QThread
{
Q_OBJECT
public:
explicit MyThread1( int ID, QAudioInput *spk, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketerror);
public slots:
void sendData();
void disconnected();
private:
QTcpSocket *socket;
int socketDescriptor;
QAudioInput *speaker;
};
#endif // MYTHREAD_H
in file mythread.cpp
#include "mythread.h"
MyThread1::MyThread1( int ID, QAudioInput *spk, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
this->speaker = spk;
}
void MyThread1::run()
{
qDebug() << " Thread started";
socket = new QTcpSocket();
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
emit error(socket->error());
return;
}
connect( speaker->start(), SIGNAL( readyRead() ), this, SLOT( sendData() ) , Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
qDebug() << socketDescriptor << " Microphone connected";
exec();
}
void MyThread1::sendData()
{
QByteArray Data = speaker->start()->readAll();
QDataStream l_vStream(&Data, QIODevice::WriteOnly);
l_vStream.setByteOrder(QDataStream::LittleEndian);
socket->write(Data, Data.length());
socket->waitForBytesWritten();
}
void MyThread1::disconnected( )
{
qDebug() << socketDescriptor << "Mic Disconnected";
speaker->stop();
delete speaker;
socket->deleteLater();
exit(0);
}
in file main.cpp
#include <QCoreApplication>
#include <myserver.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyServer server;
server.startServer();
return a.exec();
}
Any help would really be appreciated. Thanks.
I'm developing a server that responds multiple connections from a client. But I have a problem where I have not found any solution.
I created a class (TcpSocket) for QTcpSocket, which separates the signals and slots for each connection.
But my server is not recognizing the signal of this class, it looks for QTcpSocket, and not by TcpSocket.
I'll post the code, maybe you understand better, because my English is not good.
tcpsocket.h
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include <QObject>
#include <QtNetwork>
class TcpSocket: public QTcpSocket
{
Q_OBJECT
QTcpSocket *Socket;
public:
TcpSocket (QTcpSocket *);
virtual ~TcpSocket();
public slots:
void slotReadyRead();
void slotConnected();
void slotDisconnected();
signals:
void dataReady (TcpSocket *sckt);
void newConnection(TcpSocket *sckt);
void lostConnection(TcpSocket *sckt);
};
#endif // TCPSOCKET_H
tcpsocket.cpp
#include "tcpsocket.h"
TcpSocket::TcpSocket(QTcpSocket * socket)
: Socket (socket)
{
connect(Socket, SIGNAL(readyRead()), this, SLOT (slotReadyRead()));
connect(Socket, SIGNAL(connected()), this, SLOT(slotConnected()));
connect(Socket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
}
TcpSocket::~TcpSocket()
{
}
void TcpSocket::slotReadyRead()
{
emit dataReady(this);
}
void TcpSocket::slotConnected()
{
emit newConnection(this);
}
void TcpSocket::slotDisconnected()
{
emit lostConnection(this);
}
server.h
#ifndef SERVER_H
#define SERVER_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include "custom/player.h"
#include "events.h"
#include "socketmanager.h"
#include "tcpsocket.h"
#include <QMessageBox>
namespace Ui {
class Server;
}
class Server : public QMainWindow
{
Q_OBJECT
public:
explicit Server(QWidget *parent = 0);
int max_connections;
~Server();
private slots:
...
void client_Disconnected(TcpSocket *socket);
void client_SendedBytes(qint64 bytes);
void client_GetBytes(TcpSocket* socket);
...
private:
Ui::Server *ui;
QTcpServer *server;
QList<TcpSocket *> client;
...
};
#endif // SERVER_H
server.cpp
int j; // connection count
void Server::server_Connected()
{
client.insert(j, (TcpSocket*)server->nextPendingConnection());
TcpSocket *sckt = client[j];
// error:
connect(sckt, SIGNAL(newConnection(TcpSocket*)), this, SLOT(client_GetBytes(TcpSocket*)));
connect(sckt, SIGNAL(lostConnection(TcpSocket*)), this, SLOT(client_Disconnected(TcpSocket*)));
QByteArray block;
QTextStream out(&block, QIODevice::WriteOnly);
out << "accepted";
ui->log->append(QString("Host connected: %1, index %2").arg(sckt->localAddress().toString()).arg(j));
std::string stdString = "accepted";
QByteArray byteArray(stdString.c_str(), stdString.length());
qint64 len = sckt->write(byteArray);
if(len != byteArray.size())
ui->log->append("Error!");
sckt->flush();
j++;
}
void Server::client_Disconnected(TcpSocket *socket)
{
...
}
void Server::client_GetBytes(TcpSocket *socket)
{
...
}
The error:
QObject::connect: No such signal QTcpSocket::newConnection(TcpSocket*) in ..\SOLEditorServer\server.cpp:45
QObject::connect: (receiver name: 'Server')
QObject::connect: No such signal QTcpSocket::lostConnection(TcpSocket*) in ..\SOLEditorServer\server.cpp:46
QObject::connect: (receiver name: 'Server')
also full code (server)
#include "server.h"
#include "ui_server.h"
#include <QHostAddress>
Server::Server(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Server)
{
max_connections = 20;
SM = new SocketManager();
ui->setupUi(this);
server = new QTcpServer(this);
connect(server, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(server_Error()));
connect(server, SIGNAL(newConnection()), this, SLOT(server_Connected()));
event = new Events(ui->log);
setWindowFlags(Qt::WindowCloseButtonHint);
}
Server::~Server()
{
delete ui;
}
void Server::on_pushButton_clicked()
{
QHostAddress host;
host.setAddress(ui->txt_ip->text());
server->listen(host, ui->txt_port->value());
ui->log->append("Connected!");
}
void Server::server_Error()
{
ui->log->append(server->errorString());
}
int j;
void Server::server_Connected()
{
client.insert(j, (TcpSocket*)server->nextPendingConnection());
TcpSocket *sckt = client[j];
connect(sckt, SIGNAL(newConnection(TcpSocket*)), this, SLOT(client_GetBytes(TcpSocket*)));
connect(sckt, SIGNAL(lostConnection(TcpSocket*)), this, SLOT(client_Disconnected(TcpSocket*)));
QByteArray block;
QTextStream out(&block, QIODevice::WriteOnly);
out << "accepted";
ui->log->append(QString("Host connected: %1, index %2").arg(sckt->localAddress().toString()).arg(j));
std::string stdString = "accepted";
QByteArray byteArray(stdString.c_str(), stdString.length());
qint64 len = sckt->write(byteArray);
if(len != byteArray.size())
ui->log->append("Error!");
sckt->flush();
j++;
}
void Server::client_Disconnected(TcpSocket *socket)
{
ui->log->append(QString("Desconectado. (%1)").arg(socket->localAddress().toString()));
client.removeAt(client.indexOf(socket));
}
void Server::client_SendedBytes(qint64 bytes)
{
QString dataxD = QString::number(bytes);
ui->log->append(QString("%1 bytes enviados.").arg(dataxD));
}
void Server::client_GetBytes(TcpSocket *socket)
{
QByteArray buffer;
buffer.resize(socket->bytesAvailable());
socket->read(buffer.data(), buffer.size());
QString data(buffer);
if(data.startsWith("REGISTER "))
{
QString received = data.split("REGISTER ")[1];
ui->log->append(received);
QString user = received.split(":")[0];
QString key = received.split(":")[1];
playerList.append(user);
playerKey.append(key);
event->eventNewPlayer(user);
SM->sendPacketToAll(client, QString("GREETING %1").arg(user));
} else if(data.startsWith("CHAT("))
{
QString UserData = data.split("CHAT(")[1].split(")")[0];
if(!checkUser(UserData))
{
ui->log->append("Username without a valid hash!");
return;
}
QString User = getUsernameFromData(UserData);
QString Message = data.split(QString("CHAT(%1) ").arg(UserData))[1];
event->eventNewChatmessage(Message, User);
SM->sendPacketToAll(client, QString("CHAT(%1) %2").arg(User).arg(Message));
}
}
bool Server::checkUser(QString usernamedata)
{
if(!usernamedata.contains(":"))
return false;
QString username = usernamedata.split(":")[0];
QString key = usernamedata.split(":")[1];
if(!playerList.contains(username) || !playerKey.contains(key))
return false;
int playerIndex = playerList.indexOf(username);
QString hashFromList = playerKey[playerIndex];
if(hashFromList != key)
return false;
return true;
}
bool Server::checkUser2(QString username, QString key)
{
if(!playerList.contains(username) || !playerKey.contains(key))
return false;
int playerIndex = playerList.indexOf(username);
QString hashFromList = playerKey[playerIndex];
if(hashFromList != key)
return false;
return true;
}
QString Server::getUsernameFromData(QString usernamedata)
{
if(!usernamedata.contains(":"))
return "Unknow";
QString username = usernamedata.split(":")[0];
return username;
}
QString Server::getUserkeyFromData(QString usernamedata)
{
if(!usernamedata.contains(":"))
return "Unknow";
QString key = usernamedata.split(":")[1];
return key;
}
void Server::on_pushButton_2_clicked()
{
/*std::string stdString = "BANNED";
QByteArray byteArray(stdString.c_str(), stdString.length());
clientConnection->write(byteArray);*/
}
full server.h
#ifndef SERVER_H
#define SERVER_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include "custom/player.h"
#include "events.h"
#include "socketmanager.h"
#include "tcpsocket.h"
#include <QMessageBox>
namespace Ui {
class Server;
}
class Server : public QMainWindow
{
Q_OBJECT
public:
explicit Server(QWidget *parent = 0);
int max_connections;
~Server();
private slots:
void on_pushButton_clicked();
void server_Error();
void server_Connected();
void client_Disconnected(TcpSocket *socket);
void client_SendedBytes(qint64 bytes);
void client_GetBytes(TcpSocket* socket);
void on_pushButton_2_clicked();
bool checkUser(QString usernamedata);
bool checkUser2(QString username, QString key);
QString getUsernameFromData(QString usernamedata);
QString getUserkeyFromData(QString usernamedata);
private:
Ui::Server *ui;
QTcpServer *server;
QList<TcpSocket *> client;
QStringList playerList;
QStringList playerKey;
Events *event;
SocketManager *SM;
};
#endif // SERVER_H
Fixed!
Modifications:
class TcpSocket: public QTcpSocket // old
class TcpSocket: public QObject // new
// old
void dataReady (TcpSocket *sckt);
void newConnection(TcpSocket *sckt);
void lostConnection(TcpSocket *sckt);
// new
void dataReady(QTcpSocket *sckt);
void newConnection(QTcpSocket *sckt);
void lostConnection(QTcpSocket *sckt);
// old
TcpSocket::TcpSocket(QTcpSocket * socket)
: Socket (socket)
{
connect(Socket, SIGNAL(readyRead()), this, SLOT (slotReadyRead()));
connect(Socket, SIGNAL(connected()), this, SLOT(slotConnected()));
connect(Socket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
}
// new
TcpSocket::TcpSocket (QTcpSocket * socket)
: Socket (socket)
{
this->sock = socket;
connect(socket, SIGNAL(readyRead()), this, SLOT (slotReadyRead()));
connect(socket, SIGNAL(connected()), this, SLOT(slotConnected()));
connect(socket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
}
// old
void TcpSocket::slotReadyRead()
{
emit dataReady(this);
}
void TcpSocket::slotConnected()
{
emit newConnection(this);
}
void TcpSocket::slotDisconnected()
{
emit lostConnection(this);
}
// new
void TcpSocket::slotReadyRead()
{
emit dataReady(this->sock);
}
void TcpSocket::slotConnected()
{
emit newConnection(this->sock);
}
void TcpSocket::slotDisconnected()
{
emit lostConnection(this->sock);
}
// old
public:
TcpSocket (QTcpSocket *);
virtual ~TcpSocket();
// new
public:
TcpSocket (QTcpSocket *);
QTcpSocket *sock;
Done, now just use connect() function, like this:
QTcpSocket *socket = (your QTcpSocket);
TcpSocket *tcpSocket = new TcpSocket(socket);
connect(tcpSocket, SIGNAL(dataReady(QTcpSocket*)), this, SLOT(your_slot(QTcpSocket*)));
You really helped me, and sorry. Good luck, if anyone has the same problem that I had (not solved), please contact me!
I try to create a simple ssl connection between a client and a server in QtNetwork.
But I have a problem. First I run the server. Then I run the client. When I first run the client nothing happens, but when I run it second time I get QSslSocket::startServerEncryption: cannot start handshake on non-plain connection. I don't know how to fix it.
Here is the server:
//server.h
#ifndef SERVER_H
#define SERVER_H
#include <QtNetwork>
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QSslSocket>
class Server: public QTcpServer
{
Q_OBJECT
public:
Server(QObject * parent = 0);
void incomingConnection(int handle);
~Server();
public slots:
void startRead();
private:
QSslSocket* socket;
};
#endif // SERVER_H
Server Source File :
//server.cpp
#include "server.h"
#include <iostream>
#include <QByteArray>
#include <QSslCertificate>
#include <QSslKey>
using namespace std;
Server::Server(QObject* parent) :
QTcpServer(parent)
{
socket = new QSslSocket;
connect(socket, SIGNAL(encrypted()),
this, SLOT(startRead()));
listen(QHostAddress::Any, 8889);
}
void Server::startRead()
{
char buffer[1024] = { 0 };
socket->read(buffer, socket->bytesAvailable());
cout << buffer << endl;
socket->close();
}
void Server::incomingConnection(int socketDescriptor)
{
if (socket->setSocketDescriptor(socketDescriptor))
{
connect(socket, SIGNAL(encrypted()),
this, SLOT(startRead()));
QByteArray key;
QByteArray cert;
QFile file_key("/path_to_key/rsakey");
if(file_key.open(QIODevice::ReadOnly))
{
key = file_key.readAll();
file_key.close();
}
else
{
qDebug() << file_key.errorString();
}
QFile file_cert("/path_to_certificate/mycert.pem");
if(file_cert.open(QIODevice::ReadOnly))
{
cert = file_cert.readAll();
file_cert.close();
}
else
{
qDebug() << file_cert.errorString();
}
QSslKey ssl_key(key, QSsl::Rsa);
QSslCertificate ssl_cert(cert);
socket->setPrivateKey(ssl_key);
socket->setLocalCertificate(ssl_cert);
QSslConfiguration cfg = socket->sslConfiguration();
cfg.caCertificates();
socket->startServerEncryption();
}
}
Server::~Server()
{
delete socket;
}
Server Main File :
//server main
#include "server.h"
#include <QCoreApplication>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
Server server;
return app.exec();
}
Here is the Client :
//client.h
#ifndef CLIENT_H
#define CLIENT_H
#include <QtNetwork>
#include <QObject>
#include <QString>
#include <QSslSocket>
class Client: public QObject
{
Q_OBJECT
public:
Client(QObject* parent = 0);
~Client();
void start(QString address, quint16 port);
public slots:
void startTransfer();
private:
QSslSocket client;
};
#endif // CLIENT_H
Client Source File :
// client.cpp
#include "client.h"
#include <QDebug>
Client::Client(QObject* parent) :
QObject(parent)
{
connect(&client, SIGNAL(encrypted()),
this, SLOT(startTransfer()));
}
Client::~Client()
{
client.close();
}
void Client::start(QString address, quint16 port)
{
client.connectToHostEncrypted(address, port);
}
void Client::startTransfer()
{
qDebug() << "startTransfer()";
client.write("Hello, world", 13);
}
Client Main File :
//client main
#include "client.h"
#include <QCoreApplication>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
Client client;
client.start("127.0.0.1", 8889);
return app.exec();
}
Anyone can tell me what's missing?
The problem here is that QSslSocket can't be reused (I opened a bug about this QTBUG-59348), so once you call setSocketDescriptor for the second time (once a new connection arives) the internal mode is in Encrypted state.
Your code also has the issue that even if QSslSocket could be reused, you create a single socket at the constructor, so you can only accept a single connection at time. You must instead create a new QSslSocket inside incommingConnection, and NO YOU DON'T NEED to call nextPendingConnection() if you have an implementation of QTcpServer, if you do you will get two objects pointing to the same FD, one QTcpSocket and one QSsqSocket created by you.
You should try to get the socket descriptor from the nextPendingConnection and set the socket descriptor of the QSslsocket
First: You have to connect the signal of the QTcpServer::newConnection with a self made slot (for example newConnectionRecognized)
Second: Set the socketDescriptor of the QSslSocket with the socket descriptor of the QTcpServer::nextPendingConnection()->socketDescriptor
constructor:
{
server = new QTcpServer;
...
server->listen(QHostAddress::Any,1234)
...
connect(server,SIGNAL(newConnection()),this,SLOT(newConnectionRecognized()));
...
}
void SslServer::newConnectionRecognized()
{
incomingConnection(server->nextPendingConnection()->socketDescriptor());
...
}
void SslServer::incomingConnection(int socket_descriptor)
{
socket = new QSslSocket(this);
...
if (!socket->setSocketDescriptor(socket_descriptor))
{
qWarning("! Couldn't set socket descriptor");
delete socket;
return;
}
...
}
I hope it helped...
I want to write a console chat program in qt framework.I have a problem with sending messages.
Client sends messages to server but server doesn't take the messages until client program is closed.When client is closed, server displays all messages.I don't want that.I want server to get my messages when i send to it.
I wrote the codes below.You will see what i want to do if you look at main function of client.
/*
Created BY :
Creation DATE : 26/10/2012
Client interface
*/
#ifndef CLIENT_H
#define CLIENT_H
#include <QtNetwork>
#include <QObject>
#include <QtNetwork/QTcpSocket>
namespace NetworkArdic
{
class Client : public QObject
{
Q_OBJECT
public:
Client(QObject * obj = 0,QString add="localhost", quint16 port = 4000);
void SendData(QString data);
virtual ~Client();
private slots:
void ReadData();
void connected();
private:
QTcpSocket *socket;
};
}
#endif
/*
Created BY :
Creation DATE : 26/10/2012
Client source file
*/
#include "Client.h"
#include <QHostAddress>
#include <iostream>
using namespace std;
namespace NetworkArdic{
Client::Client(QObject * obj, QString add, quint16 port) : QObject(obj)
{
socket = new QTcpSocket(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(ReadData()));
connect(socket, SIGNAL(connected()), this, SLOT(connected()));
socket->connectToHost(QHostAddress(add), port);
}
Client::~Client(){
socket->close();
delete socket;
}
void Client::SendData(QString data)
{
if(!data.isEmpty())
{
socket->write(QString(data + "\n").toUtf8());
}
}
void Client::ReadData()
{
while(socket->canReadLine())
{
QString line = QString::fromUtf8(socket->readLine()).trimmed();
qDebug() << line;
}
}
void Client::connected()
{
socket->write(QString("Client : Server connection has been made (: \n").toUtf8());
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Client cli(0,"127.0.0.1",4000);
string line;
while(line!="exit"){
cout << "Message : ";
cin >> line;
cli.SendData(QString(line.c_str()));
}
return a.exec();
}
/*
Created BY :
Creation DATE : 26/10/2012
Server interface
*/
#ifndef SERVER_H
#define SERVER_H
#include <QtNetwork>
#include <QObject>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
namespace NetworkArdic
{
class Server: public QTcpServer
{
Q_OBJECT
public:
Server(QObject * parent = 0 , quint16 port = 4000);
virtual ~Server();
private slots:
void acceptConnection();
void startRead();
void disconnected();
private:
QTcpSocket * client;
};
}
#endif // SERVER_H
/*
Created BY :
Creation DATE : 26/10/2012
Server source file
*/
#include "Server.h"
#include <iostream>
using namespace std;
namespace NetworkArdic{
Server::Server(QObject* parent , quint16 port): QTcpServer(parent)
{
connect(this, SIGNAL(newConnection()),this, SLOT(acceptConnection()));
listen(QHostAddress::Any, port );
}
Server::~Server()
{
delete client;
close();
}
void Server::acceptConnection()
{
client = nextPendingConnection();
connect(client, SIGNAL(readyRead()), this, SLOT(startRead()));
connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));
qDebug() << "New client from:" << client->peerAddress().toString();
}
void Server::startRead()
{
while(client->canReadLine())
{
QString line = QString::fromUtf8(client->readLine()).trimmed();
qDebug() << "Client :" << line;
client->write(QString("Server : I've taken your message (:\n").toUtf8());
}
}
void Server::disconnected()
{
qDebug() << "Client disconnected:" << client->peerAddress().toString();
client->write(QString("Server : I wish you didn't leave ):\n").toUtf8());
}
}
Try using socket->flush() after you write the data.
http://doc.qt.digia.com/qt/qabstractsocket.html#flush
You used the code below to read socket data.
void Server::startRead()
{
while(client->canReadLine())
{
QString line = QString::fromUtf8(client->readLine()).trimmed();
qDebug() << "Client :" << line;
client->write(QString("Server : I've taken your message (:\n").toUtf8());
}
}
I suggest to adopt from the following code which I have tested works
while (tcp_server->hasPendingConnections()) {
client = tcp_server->nextPendingConnection();
client->waitForReadyRead(100);
QByteArray byteArray = client->readAll();
QString s_data = byteArray.data();
// Process s_data
client->close();
client->abort();
}