PDA

View Full Version : Problem with simple TCP chat client-server



ziele
17th January 2016, 15:28
Hi, im new in QT. I have QT 5.5 and i create a very simple chat client-server based on TCP. But when i clicked button on server window to send message, application crashed. Client aplication doesn't get any errors, so i think it's working. I dont know how to fix it :/

Thanks for any reply!!

This is my code that i made:
server.pro

#-------------------------------------------------
#
# Project created by QtCreator 2016-01-17T12:45:39
#
#-------------------------------------------------

QT += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = server
TEMPLATE = app


SOURCES += main.cpp\
server.cpp

HEADERS += server.h

FORMS += server.ui

server.h

#ifndef SERVER_H
#define SERVER_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QList>

namespace Ui {
class server;
}

class server : public QMainWindow
{
Q_OBJECT

public:
explicit server(QWidget *parent = 0);
~server();

public slots:
void connect_new();
void leer_socketclient();

private slots:
void on_pushButton_clicked();

private:
Ui::server *ui;
QTcpServer *tcpserver;
QTcpSocket *tcpclient;
};

#endif // SERVER_H

server.cpp

#include "server.h"
#include "ui_server.h"

server::server(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::server)
{
ui->setupUi(this);

tcpserver = new QTcpServer (this);
tcpserver->newConnection();

tcpserver->listen(QHostAddress::LocalHost, 1234);
connect(tcpserver, SIGNAL(newConnection()), this, SLOT(connect_new()));
}

server::~server()
{
delete ui;
}

void server::connect_new()
{
tcpclient = tcpserver->nextPendingConnection();
connect(tcpclient, SIGNAL(readyRead()), this, SLOT(leer_socketclient()));
}

void server::leer_socketclient()
{
QByteArray buffer;
buffer.resize( tcpclient->bytesAvailable() );
tcpclient->read( buffer.data(), buffer.size() );
ui->plainTextEdit->setReadOnly( true );
ui->plainTextEdit->appendPlainText( QString (buffer));
}

void server::on_pushButton_clicked()
{
tcpclient->write( ui->lineEdit->text().toLatin1().data(), ui->lineEdit->text().size());
ui->lineEdit->clear();
}

main.cpp

#include "server.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
server w;
w.show();

return a.exec();
}

=========================================
and client if you check

client.pro

#-------------------------------------------------
#
# Project created by QtCreator 2016-01-17T12:22:05
#
#-------------------------------------------------

QT += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = client
TEMPLATE = app


SOURCES += main.cpp\
client.cpp

HEADERS += client.h

FORMS += client.ui

client.h

#ifndef CLIENT_H
#define CLIENT_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QHostAddress>
#include <QList>

namespace Ui {
class client;
}

class client : public QMainWindow
{
Q_OBJECT

public:
explicit client(QWidget *parent = 0);
~client();


private slots:
void on_pushButton_clicked();

public slots:
void leer_socketserver();

private:
Ui::client *ui;

QTcpSocket *tcpclient;
};

#endif // CLIENT_H

client.cpp

#include "client.h"
#include "ui_client.h"

client::client(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::client)
{
ui->setupUi(this);

tcpclient = new QTcpSocket (this);

tcpclient->connectToHost( QHostAddress::LocalHost , 1234);

connect (tcpclient, SIGNAL (readyRead()), this, SLOT (leer_socketserver()));
}

client::~client()
{
delete ui;
}

void client::on_pushButton_clicked()
{
tcpclient->write( ui->lineEdit->text().toLatin1().data(), ui->lineEdit->text().size());
ui->lineEdit->clear();
}

void client::leer_socketserver()
{
QByteArray buffer;
buffer.resize( tcpclient->bytesAvailable() );
tcpclient->read( buffer.data(), buffer.size() );
ui->plainTextEdit->setReadOnly( true );
ui->plainTextEdit->appendPlainText( QString (buffer));
}

main.cpp

#include "client.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
client w;
w.show();

return a.exec();
}

=========================
server.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>server</class>
<widget class="QMainWindow" name="server">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>335</height>
</rect>
</property>
<property name="windowTitle">
<string>server</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>100</x>
<y>200</y>
<width>261</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>200</y>
<width>91</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;Wiadomosc:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>91</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Chat</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>250</x>
<y>230</y>
<width>111</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Wyslij na client</string>
</property>
</widget>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>341</width>
<height>151</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

anda_skoa
17th January 2016, 15:34
Are you sure server::tcpclient is a valid pointer when you call functions on it in the slot connected to the button?

Better initialize to 0 and check for != 0

Also no need to call signal "newConnection" in line 11 of the server constructor.

Cheers,
_

ziele
17th January 2016, 15:42
After 6 hours i figured what i made wrong.
In server.cpp


tcpserver->newConnection();
That line is wrong.


It's should be that

tcpserver->setMaxPendingConnections(1);
//and add this line
tcpclient = new QTcpSocket (this);


@Edit
But now, a message doesn't send to anyone( client->server | server -> client)

mhm...

@Edit 2
Now that i mentioned, if i delete this line

tcpserver->setMaxPendingConnections(1);
message is sending.

But, only with 1 pc :/

If i tried on 2 pc connected to one router, server side get me this:

QIODevice::write (QTcpSocket): device not open
in Application Output

Any ideas?

anda_skoa
17th January 2016, 21:12
tcpserver->newConnection();
That line is wrong.

Yes, as I said :)



It's should be that

//and add this line
tcpclient = new QTcpSocket (this);

No, because you don't want to connect to clients but accept client connections



But, only with 1 pc :/

Yes, because your handler for newConnection() overwrites a single QTcpSocket variable.


Any ideas?
Yes, store the accepted connections in a list or map, not in a single pointer variable.

Cheers,
_

ziele
18th January 2016, 19:08
I figured a solution.
I made a server to accept connect to any client not only localhost, and in client instead of localhost i connect to ip 192.168....
And that work on 2 different PC on same LAN. THANKS FOR HELP :)