2017-01-11 1 views
0

Qt에서 서버를 만들려고합니다. 때로는 제대로 작동하지만 때로는 처음 클라이언트가 연결을 시도 할 때 충돌이 발생합니다. 공통 QTcpServer와 QTcpSocket에서 상속 된 MySocket을 사용합니다.클라이언트 연결시 QT 서버가 충돌하는 경우가 있습니다.

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; 
}; 

시작 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); 

그리고 충돌의 순간 - 주석 전에

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-> log_model = log_model ;. programm에있는 경우 충돌이 발생하지만 충돌하지 않으면 충돌이 발생하지 않습니다. 내가 뭘 잘못하고 있니?

+0

'server-> nextPendingConnection()'에서 얻은'QTcpSocket * '을 자신의'MySocket *'클래스로 캐스팅 할 수 있기를 기대하는 이유는 무엇입니까? – E4z9

+0

흠, 나는 상속인이 그렇게 할 수 있다고 생각했다. 내가하려고하면 MySocket 생성자를 놓치지? – luden

답변

2

QTcpServer의 기본 구현은 새 연결이 들어올 때 QTcpSocket의 새 인스턴스를 만들고 이는 server->nextPendingConnection()을 호출 할 때 얻는 것입니다. 이 인스턴스를 자신의 MySocket으로 전송하면 런타임에 예측할 수없는 범위까지 실패합니다.

자신의 QTcpSocket 서브 클래스를 사용하려면, 당신은 QTcpServer 서브 클래스에 incomingConnection(qintptr socketDescriptor)을 구현할 자신의 소켓 클래스의 인스턴스를 생성하고 addPendingConnection으로 보류중인 연결에 추가해야합니다.

사이드 노트 : You should avoid using C-style cast (MySocket *), 안전하지 않습니다. 전송이 성공할 경우 static_cast을 사용하고 그렇지 않은 경우 dynamic_cast을 사용합니다 (결과를 확인하십시오).

관련 문제