1. 程式人生 > >qt 實現簡單聊天(一個服務器和多個客服端)

qt 實現簡單聊天(一個服務器和多個客服端)

qt

源碼地址:https://github.com/haidragon/easyChat
思路 :

  1. 一個服務器一直接聽某個 ip 的某個端口
    listen(QHostAddress::Any,port);
    2.一個服務器有一個容器保存所有各客服端的鏈接(每個鏈接都是一個類)。QList<TcpClientSocket> tcpClientSocketList;每當一個客服端鏈接上那個服務器一直接聽的套節字時。服務器會自動調用一個函數。incomingConnection(qintptr socketDescriptor);(這個函數是繼承過來的虛函數)
    3.每次調用鏈接函數時 new 一個新的客服端流(也就是另外增加一個類。這個類就是客服端流類)TcpClientSocket

    tcpClientSocket=new TcpClientSocket(this);
    4.服務器管理所有的服端流。
    5.每次新創建一個客服端流時會往流裏寫入鏈接成功的數據。

    //鏈接後就往套節字裏發內容
    void TcpClient::slotConnected()
    {
    sendBtn->setEnabled(true);
    enterBtn->setText(tr("離開"));
    
    int length=0;
    QString msg=userName+tr(":Enter Chat Room");
    if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())
    {
        return;
    }
    }

    6.由於每個客服端流是分開的只有服務器能夠知道所有流裏的數據。因此每當有客服端流中有數據時在服務器中會發給其它客服端流。其它客服端流只要流中有數據會一直更新。實現了簡單群聊。

    void Server::updateClients(QString msg,int length)
    {
    emit updateServer(msg,length);
    //這裏是往每個鏈接裏與 
    for(int i=0;i<tcpClientSocketList.count();i++)
    {
        QTcpSocket *item = tcpClientSocketList.at(i);
        if(item->write(msg.toLatin1(),length)!=length)
        {
            continue;
        }
    }
    }

    7.服務器端也實現了 ui 見面
    8.每個客服端只要斷開鏈接。它就會在這個流中發一個斷開信號。因為服務器保存了每個客服端的流。當某個客服端流斷開時會發一個斷開信號同時帶上標誌。服務器只要檢測到了這個信號會及時處理。

    
    else
    {
        int length=0;
        QString msg=userName+tr(":Leave Chat Room");
        if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg. length())
        {
            return;
        }
    
        tcpSocket->disconnectFromHost();
    
        status=false;
    }
    
        /////////  tcpclientsocket類
        void TcpClientSocket::slotDisconnected()
    {
    emit disconnected(this->socketDescriptor());
    }
    ///server類
    void Server::slotDisconnected(int descriptor)
    {
    for(int i=0;i<tcpClientSocketList.count();i++)
    {
        QTcpSocket *item = tcpClientSocketList.at(i);
        if(item->socketDescriptor()==descriptor)
        {
            tcpClientSocketList.removeAt(i);
            return;
        }
    }
    return;
    }

qt 實現簡單聊天(一個服務器和多個客服端)