我试图在Qt上制作服务器。有时它运行良好,但有时它会在第一个客户端尝试连接时崩溃。 我使用常见的QTcpServer和继承自QTcpSocket的MySocket。
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);
};
我有一个全局日志(QListView)和一个log_model(QStandardItemModel)。哪个用,嗯,像日志。并且每个套接字都必须指向两者。
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;
};
开始辩护
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);
崩溃时刻 -
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()));*/
}
评论前的最后一个字符串 - clientSocket-&gt; log_model = log_model;。如果它在程序中,它会崩溃,但如果没有 - 程序不会崩溃。我做错了什么?
答案 0 :(得分:2)
QTcpServer
的默认实现会在新连接进入时创建QTcpSocket
的新实例,这就是您在调用server->nextPendingConnection()
时获得的内容。将此实例强制转换为您自己的MySocket
将在运行时失败(到不可预测的扩展)。
要使用您自己的QTcpSocket
子类,您需要在QTcpServer
子类中重新实现incomingConnection(qintptr socketDescriptor)
,创建自己的套接字类的实例,并使用{将其添加到挂起的连接中{3}}
旁注:addPendingConnection
,这是不安全的。如果您确定演员表会成功,请使用static_cast
;如果不是,请使用dynamic_cast
(然后查看结果)。