1

I'm trying to make server on Qt. Sometimes it works good, but sometimes it crashes when first client try connect. I use common QTcpServer and my MySocket inherited from QTcpSocket.

    class MySocket : public QTcpSocket
{
public:
    CShip *parentShip;
    int pt_type;
    int descriptor;
    QListView *log;
    QStandardItemModel *log_model;
public:
    MySocket();
    qint64 MyWrite(char* data, quint64 maxSize);
    void LogAddString(QString str);
};

I have a global log(QListView) and a log_model(QStandardItemModel). Which use, hmmm, like log. And every socket must have pointers to both.

    class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void LogAddString(QString str);

private slots:
    void newUser();
    void slotReadClient();
    void UserCreate();
    void DataUpdate();
    void UserDisconnected();

private:
    Ui::MainWindow *ui;
    QTcpServer *server;
    QMap<int, MySocket*> SClients;
    MyTableModel *table_model;
    QStandardItemModel *log_model;
    QTimer *timer_update;
};

Start defenition

log_model = new QStandardItemModel();
ui->log->setModel(log_model);

server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(newUser()));
server->listen(QHostAddress::Any, 63258); 

And crash moment -

    void MainWindow::newUser()
{
    MySocket* clientSocket;
    clientSocket = (MySocket*)(server->nextPendingConnection());
    clientSocket->log = ui->log;
    clientSocket->log_model = log_model;
    /*clientSocket->pt_type = 0;
    int idusersocs = clientSocket->socketDescriptor();
    SClients[idusersocs] = clientSocket;
    clientSocket->descriptor = idusersocs;
    connect(clientSocket, SIGNAL(readyRead()), this, SLOT(slotReadClient()));
    connect(clientSocket, SIGNAL(disconnected()), this, SLOT(UserDisconnected()));*/
}

Last string before comment - clientSocket->log_model = log_model;. If it in programm, it would crash, but if not - programm not crash. What I am doing wrong?

luden
  • 113
  • 1
  • 1
  • 4
  • What makes you expect to be able to cast the `QTcpSocket *` that you get from `server->nextPendingConnection()` to your own `MySocket *` class? – E4z9 Jan 11 '17 at 12:31
  • Hmmm, I thought heir can do that. When I try do that I miss MySocket constructor? – luden Jan 11 '17 at 12:44

1 Answers1

3

The default implementation of QTcpServer creates a new instance of QTcpSocket when a new connection comes in, and that is what you get when calling server->nextPendingConnection(). Casting this instance to your own MySocket will fail at runtime (to an unpredictable extend).

To use your own QTcpSocket subclass, you need to reimplement incomingConnection(qintptr socketDescriptor) in a QTcpServer subclass, create an instance of your own socket class, and add it to the pending connections with addPendingConnection.

Side note: You should avoid using C-style cast (MySocket *), it is unsafe. Use static_cast if you are sure that the cast will succeed, or dynamic_cast if you aren't (and then check the result).

Community
  • 1
  • 1
E4z9
  • 1,713
  • 9
  • 11