Qt學習心得之網絡編程簡單的局域網聊天服務端創建

學而不思則罔,思而不學則殆。學習和思考是相輔相成的,經過這幾天對網絡編程的學習,收穫頗豐。接下來我將利用Qt作的一個以TcpIp協議爲傳輸方式的簡單的局域網聊天服務端與你們分享下:編程

 

首先談談我我的對Tcp協議的理解:Tcp就是網上購物,買家和買家之間的物品傳遞,快遞公司的扮演。快遞公司將賣家所要寄出的物品進行包裝,給予獨特的號碼,並從賣家獲取目的地地址,得知這些明確信息後準確將物品送到買家,買家簽收後,賣家經過快遞單號查詢到買家簽收的消息。數組

其次是這個簡單局域網聊天服務器的建立思路。以下圖是思路的框圖:服務器

 

一個服務器的創建,必需要有對外雙向通信的接口就是套接字(socket),因此須要建一個Mysocket的類,這樣才能夠將不一樣客戶端的消息發給其餘客戶端。以後還須要再建立一個Myserver的類,將每一個客戶端發送的消息經過Mysocket發送信號被接受。而後在每一個客戶端對應的每一個Myserver中將各自發送的信號發送給其餘客戶端,並再發送給serverUI界面上顯示。如圖:在MysocketMyserver以及Myserverserver之間的聯繫都是經過發送信號,並利用槽函數進行處理,因此這整個程序的關鍵是合理運用信號和槽函數,將信息順利傳達。網絡

而後是程序的展現和一些關鍵點的處理方式。socket

//========================Mysocket.c=============================//tcp

MyTcpSocket::MyTcpSocket(QObject *parent) :/*在構造函數中進行信號和槽函數的鏈接*/函數

    QTcpSocket(parent)學習

{網站

    connect(this,SIGNAL(readyRead()),     /*讀信號和對應的槽函數處理*/ui

            SLOT(slotReadyread()));

    connect(this,SIGNAL(disconnected()),   /*斷開鏈接的信號和對應的槽函數處理*/

            SLOT(slotDisconnect()));

}

void MyTcpSocket::slotReadyread()      

{

    QString msg;                    

    QByteArray ba;        /*採用QByteArray字節數組的方式客戶端發送消息進行讀取* /

    ba.resize(this->bytesAvailable());    /*判斷是否可讀*/

    this->read(ba.data(),ba.size());      /*讀取客戶端發送的消息*/

    msg=QString(ba);         /*將接收到的消息轉化爲QString類型*/

    emit updatemsg(msg,this->socketDescriptor(),this->peerAddress().toString());/*將客戶端的信息經過信號的方式發送出去(信號包括客戶端輸入內容、客戶端對應的描述符以及客戶端的IP地址)*/

}

void MyTcpSocket::slotDisconnect()   

{

    qDebug("Disconnect host");     

    emit signalDisconnect(this->socketDescriptor()); /*將斷開的客戶端所對應的描述符信號發送出去*/

}

//========================Myserver.c=============================//

MyTcpserver::MyTcpserver(QObject *parent) :   /*在構造函數中監聽*/    QTcpServer(parent)

{

    listen(QHostAddress::Any,8080);/*監放任何客戶端IP地址的連入,以及端口號爲8080*/

/**/

}

void MyTcpserver::incomingConnection(qintptr socketDescriptor){/*incomingConnection這個函數在服務端被客戶端鏈接上後自動調用此函數,傳入的參數爲該客戶端特有的描述符*/

    qDebug("incomingConnection");

    MyTcpSocket* sock = new MyTcpSocket;   /*新建一個Mysocket的對象*/

    sock->setSocketDescriptor(socketDescriptor); /*設置sock的描述符*/

    connect(sock,SIGNAL(signalDisconnect(qintptr)),   

            this,SLOT(slotDisconnect(qintptr))); /*斷開鏈接的信號和對應的槽函數處理*/

    connect(sock,SIGNAL(updatemsg(QString,qintptr,QString)),  

            this,SLOT(slotupdatemsg(QString,qintptr,QString)));/*Mysocket發送過來客戶端的信息進行處理,用於發送給UI界面*/

    connect(sock,SIGNAL(updatemsg(QString,qintptr,QString)),

            this,SLOT(slotrecivermsg(QString,qintptr,QString)));/*Mysocket發送過來客戶端的信息進行處理,再發送給其餘連入的客戶端*/

 

    clients << sock; /*建立的一個QList的容器類名爲clients,將每一個不一樣的客戶端放入到該容器中,以便後續處理*/

}

void MyTcpserver::slotDisconnect(qintptr sockfd)/*斷開槽函數處理主要是將斷開的客戶端從容器中移除*/

{

    int i=0;

    for(i=0;i<clients.count();i++){              /*遍歷容器中存入的客戶端*/

        if(clients.at(i)->socketDescriptor()==sockfd){/*當找到容器中對應的那個斷開的客戶端後,將其移除*/

            clients.removeAt(i);

            break;

        }

    }

}

void MyTcpserver::slotupdatemsg(QString msg,qintptr sockfd,QString IP)

{

    qDebug()<<"slotupdatemsgServer";

    emit updatemsgServer(msg,IP);   /*將客戶端信息經過信號的方式傳送給UI界面*/

}

void MyTcpserver::slotrecivermsg(QString msg,qintptr sockfd,QString IP)

{

        QString message;

        message=IP+" : "+msg;     /*設定回覆給其餘客戶端的信息格式*/

        int i=0;

        for(i=0;i<clients.count();i++){

            if(clients.at(i)->socketDescriptor()!=sockfd){ /*遍歷容器中存入的客戶端*/

                clients.at(i)->write(message.toLatin1(),message.length());/*將消息發送給除本身之外的全部連入的客戶端*/

 

            }

        }

}

//========================server.c=============================//

tcpserver::tcpserver(QWidget *parent) :  /*在構造函數中進行信號和槽函數的鏈接*/

    QWidget(parent),

    ui(new Ui::tcpserver)

{

    ui->setupUi(this);       

    server = new MyTcpserver;   /*新建一個MyTcpserver對象*/

    connect(server,SIGNAL(updatemsgServer(QString,QString)),

            this,SLOT(recivermsg(QString,QString)));/*MyTcpservert發送過來客戶端的信息進行界面顯示處理*/

 

}

 

tcpserver::~tcpserver()  /*析構函數中釋放ui*/

{

    delete ui;

}

void tcpserver::recivermsg(QString msg,QString IP)

{

    qDebug("recivermsg");

    qDebug()<<msg;

    ui->listWidget->addItem(IP+" : "+msg);  /*顯示發送的信號到UI界面上*/

}

最後感謝匯文,在匯文培訓學習也有三個多月了,在這個融洽的你們庭中,感受天天都很充實,在學習中實踐,在實踐中收穫,願本身在未來能找到一份合適的工做。附上匯文網站可供瀏覽:www.huiwen.com

相關文章
相關標籤/搜索