Okay, I tried several things to get what I want but so far it is only partly working. I try to peace together the parts that I found on the web to get a client and a sever code that could be added to an existing project. Goal is to get two programs talking to each other. My sources are the link and the chatterbox example. Hopefully some of you can contribute to it so that there is an example code at the end of this.
First the sever part. Code needs to be added to your project:
xy.pro (Server)
QT +=network
QT +=network
To copy to clipboard, switch view to plain text mode
mainwindow.h (Server)
#include <QTcpSocket>
#include <QTcpServer>
#include <QNetworkInterface>
#include <QRegExp>
[...]
private slots:
void readyRead();
void disconnected();
void incomingConnection();
[...]
private:
//Server
QSet<QTcpSocket*> clients;
QMap<QTcpSocket*,QString> users;
#include <QTcpSocket>
#include <QTcpServer>
#include <QNetworkInterface>
#include <QRegExp>
[...]
private slots:
void readyRead();
void disconnected();
void incomingConnection();
[...]
private:
//Server
QTcpServer *tcpServer;
QSet<QTcpSocket*> clients;
QMap<QTcpSocket*,QString> users;
To copy to clipboard, switch view to plain text mode
mainwindow.cpp (Server)
MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow){
ui->setupUi(this);
// Server
if (!tcpServer->listen()) {
QMessageBox::critical(this, tr
("Server Error"), tr
("The server could not be started: %1.").
arg(tcpServer
->errorString
()));
close();
return;
}
// use the first non-localhost IPv4 address
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 we did not find one, use IPv4 localhost
if (ipAddress.isEmpty())
// output you need to know the IP and the port the server listens to
qDebug() << ipAddress << tcpServer->serverPort();
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
[...]
}
// Server Functions and Slots
void MainWindow::incomingConnection(){
QTcpSocket *client
= tcpServer
->nextPendingConnection
();
// client->setSocketDescriptor(socketfd); <- this is from the original code not sure if I need it or not and where to get the socketfd.
clients.insert(client);
qDebug() << "New client from:" << client->peerAddress().toString();
connect(client, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));
}
void MainWindow::readyRead(){
while(client->canReadLine()) {
qDebug() << "Read line:" << line;
if(meRegex.indexIn(line) != -1){
users[client] = user;
}else if(users.contains(client)){
qDebug() << "User:" << user;
qDebug() << "Message:" << message;
}else{
qWarning() << "Got bad message from client:" << client->peerAddress().toString() << line;
}
}
}
void MainWindow::disconnected(){
clients.remove(client);
users.remove(client);
qDebug() << "Lost connection to Client: << user << client->peerAddress().toString());
}
// End Server Functions and Slots
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow){
ui->setupUi(this);
// Server
tcpServer = new QTcpServer(this);
if (!tcpServer->listen()) {
QMessageBox::critical(this, tr("Server Error"), tr("The server could not be started: %1.").arg(tcpServer->errorString()));
close();
return;
}
QString ipAddress;
QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
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 we did not find one, use IPv4 localhost
if (ipAddress.isEmpty())
ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
// output you need to know the IP and the port the server listens to
qDebug() << ipAddress << tcpServer->serverPort();
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
[...]
}
// Server Functions and Slots
void MainWindow::incomingConnection(){
QTcpSocket *client = tcpServer->nextPendingConnection();
// client->setSocketDescriptor(socketfd); <- this is from the original code not sure if I need it or not and where to get the socketfd.
clients.insert(client);
qDebug() << "New client from:" << client->peerAddress().toString();
connect(client, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));
}
void MainWindow::readyRead(){
QTcpSocket *client = (QTcpSocket*)sender();
while(client->canReadLine()) {
QString line = QString::fromUtf8(client->readLine()).trimmed();
qDebug() << "Read line:" << line;
QRegExp meRegex("^/me:(.*)$");
if(meRegex.indexIn(line) != -1){
QString user = meRegex.cap(1);
users[client] = user;
}else if(users.contains(client)){
QString message = line;
QString user = users[client];
qDebug() << "User:" << user;
qDebug() << "Message:" << message;
}else{
qWarning() << "Got bad message from client:" << client->peerAddress().toString() << line;
}
}
}
void MainWindow::disconnected(){
QTcpSocket *client = (QTcpSocket*)sender();
clients.remove(client);
QString user = users[client];
users.remove(client);
qDebug() << "Lost connection to Client: << user << client->peerAddress().toString());
}
// End Server Functions and Slots
To copy to clipboard, switch view to plain text mode
And the code on the client side:
xy.pro
QT += network
QT += network
To copy to clipboard, switch view to plain text mode
mainwindow.h (Client)
#include <QTcpSocket>
#include <QtNetwork>
[...]
private slots:
void connectToServer();
void readyRead();
void connected();
void enableGetFortuneButton();
void sessionOpened();
void on_connectButton_clicked();
[...]
private:
Ui::MainWindow *ui;
// Client
QNetworkSession *networkSession;
#include <QTcpSocket>
#include <QtNetwork>
[...]
private slots:
void connectToServer();
void readyRead();
void connected();
void displayError(QAbstractSocket::SocketError socketError);
void enableGetFortuneButton();
void sessionOpened();
void on_connectButton_clicked();
[...]
private:
Ui::MainWindow *ui;
// Client
QTcpSocket *tcpSocket;
QNetworkSession *networkSession;
void sentMSG(QString msg);
To copy to clipboard, switch view to plain text mode
mainwindow.ui (Client) needs to have to inputs for the Server IP and the server port plus an connect button. To display messages a window is also required.
mainwindow.cpp (Client)
MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow){
ui->setupUi(this);
// Setup Client
// find out which IP to connect to
// use the first non-localhost IPv4 address
for (int i = 0; i < ipAddressesList.size(); ++i) {
ipAddressesList.at(i).toIPv4Address()) {
ipAddress = ipAddressesList.at(i).toString();
break;
}
}
// if we did not find one, use IPv4 localhost
if (ipAddress.isEmpty())
connect(ui
->hostLineEdit,
SIGNAL(textChanged
(QString)),
this,
SLOT(enableConnectButton
()));
connect(ui
->portLineEdit,
SIGNAL(textChanged
(QString)),
this,
SLOT(enableConnectButton
()));
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readReady()));
connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected()));
}
// Network Functions
void MainWindow::on_connectButton_clicked(){
connectToServer();
}
void MainWindow
::sentMSG(QString msg
){ msg = msg.trimmed();
qint64 bytes = 0;
if(!msg.isEmpty())
bytes = tcpSocket->write(msg.toUtf8());
if(bytes == -1)
qDebug() << "Error while sending data";
else
qDebug() << bytes << "sent.";
}
void MainWindow::connected(){
// And send our username to the chat server.
sentMSG("/me:"+clientName+"\n");
}
// End Network Functions
//Slots
void MainWindow::connectToServer(){
ui->connectButton->setEnabled(false);
tcpSocket->abort();
tcpSocket->connectToHost(ui->hostLineEdit->text(), ui->portLineEdit->text().toInt());
}
void MainWindow::readReady(){
while(tcpSocket->canReadLine()){
// Using QRegExp allows us to specify different types of messages. Normal messges look like this: "username:The message"
QRegExp messageRegex
("^([^:]+):(.*)$");
if(messageRegex.indexIn(line) != -1){
QString user
= messageRegex.
cap(1);
QString message
= messageRegex.
cap(2);
ui->log->append("<b>" + user + "</b>: " + message);
}else{
aDebug() << "Bad message.";
}
}
}
switch (socketError) {
break;
tr("The host was not found. Please check the "
"host name and port settings."));
break;
tr("The connection was refused by the peer. "
"Make sure the fortune server is running, "
"and check that the host name and port "
"settings are correct."));
break;
default:
tr("The following error occurred: %1.")
.arg(tcpSocket->errorString()));
}
ui->connectButton->setEnabled(true);
}
void MainWindow::enableConnectButton(){
ui->connectButton->setEnabled(!ui->hostLineEdit->text().isEmpty() && !ui->portLineEdit->text().isEmpty());
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow){
ui->setupUi(this);
// Setup Client
// find out which IP to connect to
QString ipAddress;
QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
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 we did not find one, use IPv4 localhost
if (ipAddress.isEmpty())
ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
tcpSocket = new QTcpSocket(this);
connect(ui->hostLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableConnectButton()));
connect(ui->portLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableConnectButton()));
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readReady()));
connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected()));
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
}
// Network Functions
void MainWindow::on_connectButton_clicked(){
connectToServer();
}
void MainWindow::sentMSG(QString msg){
msg = msg.trimmed();
qint64 bytes = 0;
if(!msg.isEmpty())
bytes = tcpSocket->write(msg.toUtf8());
if(bytes == -1)
qDebug() << "Error while sending data";
else
qDebug() << bytes << "sent.";
}
void MainWindow::connected(){
// And send our username to the chat server.
sentMSG("/me:"+clientName+"\n");
}
// End Network Functions
//Slots
void MainWindow::connectToServer(){
ui->connectButton->setEnabled(false);
tcpSocket->abort();
tcpSocket->connectToHost(ui->hostLineEdit->text(), ui->portLineEdit->text().toInt());
}
void MainWindow::readReady(){
while(tcpSocket->canReadLine()){
QString line = QString::fromUtf8(tcpSocket->readLine()).trimmed();
// Using QRegExp allows us to specify different types of messages. Normal messges look like this: "username:The message"
QRegExp messageRegex("^([^:]+):(.*)$");
if(messageRegex.indexIn(line) != -1){
QString user = messageRegex.cap(1);
QString message = messageRegex.cap(2);
ui->log->append("<b>" + user + "</b>: " + message);
}else{
aDebug() << "Bad message.";
}
}
}
void MainWindow::displayError(QAbstractSocket::SocketError socketError){
switch (socketError) {
case QAbstractSocket::RemoteHostClosedError:
break;
case QAbstractSocket::HostNotFoundError:
QMessageBox::information(this, tr("Fortune Client"),
tr("The host was not found. Please check the "
"host name and port settings."));
break;
case QAbstractSocket::ConnectionRefusedError:
QMessageBox::information(this, tr("Fortune Client"),
tr("The connection was refused by the peer. "
"Make sure the fortune server is running, "
"and check that the host name and port "
"settings are correct."));
break;
default:
QMessageBox::information(this, tr("Fortune Client"),
tr("The following error occurred: %1.")
.arg(tcpSocket->errorString()));
}
ui->connectButton->setEnabled(true);
}
void MainWindow::enableConnectButton(){
ui->connectButton->setEnabled(!ui->hostLineEdit->text().isEmpty() && !ui->portLineEdit->text().isEmpty());
}
To copy to clipboard, switch view to plain text mode
So for the code can connect to the server but messages from the client to the server are ignored. I get the information that the message was sent but the server does not react to it.
There are probably tons of errors in here. So I would be grateful if some could help me clean up.
Thanks.
Bookmarks