Problem TCP chat client-server
-
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 :/
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 there is no errors#------------------------------------------------- # # 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><html><head/><body><p><span style=" font-size:11pt;">Wiadomosc:</span></p></body></html></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>
-
Hi and welcome to devnet
Are you aware of the fotune client and server examples?
They basically do exactly the same thing. When both compiled you can run them on the same machine and debug one of the applications. In your case you can use either of the examples and combine with your own applications. This eliminates the ambiguity of knowing that your other application is working properly.
-
I guess server::connect_new() was not called before you press the button, so tcpclient is an invalid pointer. The button should be disabled if there is no connection and in on_pushButton_clicked you should check whether tcpclient is a NULL pointer or not.
void server::connect_new() { tcpclient = tcpserver->nextPendingConnection(); connect(tcpclient, SIGNAL(readyRead()), this, SLOT(leer_socketclient())); } void server::on_pushButton_clicked() { tcpclient->write( ui->lineEdit->text().toLatin1().data(), ui->lineEdit->text().size()); ui->lineEdit->clear(); }
-
Hi koahnig.
Yes, i saw fortune server and client example. But this is only one side send message.@zoe9 although its not exactly what you are looking for you should still have a look at the examples and especially on the way Messages are sent and received.
From the example:
"Now, TCP is based on sending a stream of data, so we cannot expect to get the entire [Message] in one go. Especially on a slow network, the data can be received in several small fragments. QTcpSocket buffers up all incoming data and emits readyRead() for every new block that arrives, and it is our job to ensure that we have received all the data we need before we start parsing. The server's response starts with the size of the packet, so first we need to ensure that we can read the size, then we will wait until QTcpSocket has received the full packet."