qt4 chat c++

0

Witam, napisałem swój pierwszy czat, ale opierał się on na samych sygnałach przez co spamując na czacie nie dochodziły wiadomości.
Chciałem stworzyć wątek, nie wiem czy w dobry sposób, sami ocenicie, niby nie wysyła żadnego komunikatu o bledzie ale mimo to w watku nie wysyła żadnych informacji do klienta, oto kod:

Main.cpp:

#include <QtGui/QApplication>
#include "widget.h"

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

    return a.exec();
}
 

Thread.h:

#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include <QList>
#include <QtNetwork/QTcpSocket>
#include <QDateTime>
#include <QTcpServer>


class Recive : public QThread
{
public:
    void run();
    Recive(QList<QTcpSocket*> *host_list, QList<QString> *logins_list, QTcpServer *tcpServer);
    ~Recive();

private:
    QList<QTcpSocket*> *hosts_list;
    QList<QString> *login_list;
    QTcpServer *server;
};

#endif // THREAD_H
 

widget.h:

 #ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QTcpServer>
#include <QList>
#include <QDateTime>
#include "Thread.h"

namespace Ui {
    class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
    QTcpServer *tcpServer;
    QList<QTcpSocket*> *host_list;
    QList<QString> *login_list;
    void delete_host_from_list(int i);
    void update_host_list();
    Recive *recive;

private slots:
    void server_start();
    void server_stop();
    void incomming_connection();
    void host_disconnected();
    void read_message();
};

#endif // WIDGET_H

Thread.cpp:

 #include <Thread.h>

Recive::Recive(QList<QTcpSocket*> *host_list, QList<QString> *logins_list, QTcpServer *tcpServer)
{
    hosts_list = host_list;
    login_list = logins_list;
    server = tcpServer;
}

Recive::~Recive()
{

}

void Recive::run()
{
    forever
    {
        for(int i=0; i<hosts_list->size() && hosts_list->at(i)->bytesAvailable(); i++)
        {
            QTcpSocket *tcpSocket = hosts_list->at(i);
            if(tcpSocket->bytesAvailable())
            {
                QDataStream in(tcpSocket);
                in.setVersion(QDataStream::Qt_4_7);
                QChar option;
                in >> option;
                if(option=='L')
                {
                    QString login;
                    in >> login;
                    for(int i=0; i<login_list->size(); i++)
                    {
                        if(login_list->at(i)==login)
                        {
                            QByteArray block;
                            QDataStream out(&block, QIODevice::WriteOnly);
                            out.setVersion(QDataStream::Qt_4_7);
                            out << option;
                            tcpSocket->write(block);
                            break;
                        }
                        if(i==login_list->size()-1)
                        {
                            login_list->push_back(login);
                            break;
                        }
                    }
                    if(login_list->size()==0)
                    {
                        login_list->push_back(login);
                    }
                }
                else if(option=='M')
                {
                    QDateTime date;
                    QString login, message;
                    in >> date >> login >> message;
                    QByteArray block;
                    QDataStream out(&block, QIODevice::WriteOnly);
                    out.setVersion(QDataStream::Qt_4_7);
                    out << option << date << login << message;
                    for(int a=0; a<hosts_list->size(); a++)
                    {
                        hosts_list->at(a)->write(block);
                    }
                }
            }
        }
    }
}

widget.cpp:

#include "widget.h"
#include "ui_widget.h"

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

    tcpServer = new QTcpServer;

    connect(ui->start_button, SIGNAL(clicked()), this, SLOT(server_start()));
    connect(ui->stop_button, SIGNAL(clicked()), this, SLOT(server_stop()));
    login_list = new QList<QString>;
    host_list = new QList<QTcpSocket*>;

    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(incomming_connection()));
    recive = new Recive(host_list, login_list, tcpServer);
}

Widget::~Widget()
{
    delete ui;

}

void Widget::server_start()
{
    recive->start();
    tcpServer->listen(QHostAddress::Any, 1976);
    ui->massage_browser->insertPlainText("Server started\n");
    ui->start_button->setEnabled(false);
    ui->stop_button->setEnabled(true);
}

void Widget::server_stop()
{
    recive->quit();
    tcpServer->close();
    ui->massage_browser->insertPlainText("Server stoped\n");
    ui->start_button->setEnabled(true);
    ui->stop_button->setEnabled(false);
}

void Widget::incomming_connection()
{
    QTcpSocket *client = new QTcpSocket;
    client = tcpServer->nextPendingConnection();
    //connect(client, SIGNAL(readyRead()), this, SLOT(read_message()));
    connect(client, SIGNAL(disconnected()), this, SLOT(host_disconnected()));
    host_list->push_back(client);
    ui->massage_browser->insertPlainText("Host: " + client->peerAddress().toString() + " connected\n");
}

void Widget::read_message()
{
    /*QTcpSocket *tcpSocket = (QTcpSocket*) sender();
    QDataStream in(tcpSocket);
    in.setVersion(QDataStream::Qt_4_7);
    QChar option;
    in >> option;
    if(option=='L')
    {
        QString login;
        in >> login;
        for(int i=0; i<login_list.size(); i++)
        {
            if(login_list.at(i)==login)
            {
                QByteArray block;
                QDataStream out(&block, QIODevice::WriteOnly);
                out.setVersion(QDataStream::Qt_4_7);
                out << option;
                tcpSocket->write(block);
                break;
            }
            if(i==login_list.size()-1)
            {
                login_list.push_back(login);
                break;
            }
        }
        if(login_list.size()==0)
        {
            login_list.push_back(login);
        }
        update_host_list();
    }
    else if(option=='M')
    {
        QDateTime date;
        QString login, message;
        in >> date >> login >> message;
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_7);
        out << option << date << login << message;
        for(int i=0; i<host_list.size(); i++)
        {
            host_list.at(i)->write(block);
        }
    }*/
}

void Widget::host_disconnected()
{
    QTcpSocket *tcpSocket = (QTcpSocket*) sender();
    ui->massage_browser->insertPlainText("Host: " + tcpSocket->peerAddress().toString() + " disconnected\n");
    int index = host_list->indexOf(tcpSocket);
    tcpSocket->deleteLater();
    delete_host_from_list(index);
}

void Widget::delete_host_from_list(int i)
{
    host_list->removeAt(i);
    login_list->removeAt(i);
    update_host_list();
}

void Widget::update_host_list()
{
    ui->host_list->clear();
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_7);
    QChar option = 'H';
    out << option;
    int a = login_list->size();
    out << a;
    for(int i=0; i<login_list->size(); i++)
    {
        ui->host_list->addItem(login_list->at(i));
        out << login_list->at(i);
    }
    for(int i=0; i<host_list->size(); i++)
    {
    //    host_list.at(i)->write(block);
    }
}
 

Prosiłbym, jeżeli możecie aby zajrzeć do klasy głównie z wątkiem i powiedzieć, jeżeli wiecie dlaczego nie wysyła żadnych wiadomości.

Z góry dziękuję za pomoc.

0
rybak16 napisał(a)

Prosiłbym, jeżeli możecie aby zajrzeć do klasy głównie z wątkiem i powiedzieć, jeżeli wiecie dlaczego nie wysyła żadnych wiadomości.

Nie czytałem szczegółowo kodu(po pobieżnym spojrzeniu jest straszny, memory leaki, wesołe copy paste, wiele zagnieżdżonych bloków kodu, zbędna komplikacja, brak komentarzy), wciskałem tylko ctrl-f i wyszukiwałem słowa kluczowe.

Nie wiem dokładnie co może być problemem, ale napiszę co podejrzewam:

Call this function if you need QAbstractSocket to start sending buffered data immediately. The number of bytes successfully written depends on the operating system. In most cases, you do not need to call this function, because QAbstractSocket will start sending data automatically once control goes back to the event loop. In the absence of an event loop, call waitForBytesWritten() instead.

http://doc.trolltech.com/4.7/qabstractsocket.html#flush

Ponieważ nie masz even loopa w threadzie i nigdzie nie wyszukałem waitForBytesWritten, ani flusha, zgaduję że nieopróżnianie buforów jest tą przyczyną. Za mało danych podałeś abym mógł wiedzieć na pewno.

Najlepiej jeśli potraktujesz ten kod jako pierwszy prototyp i go odrzucisz. Napisz tego czata jeszcze raz, rozszerzanie możliwości obecnego kodu jest/będzie bolesne.

0

OK tak zrobie, wielkiie dzięki

1 użytkowników online, w tym zalogowanych: 0, gości: 1