Qt網絡編程—TCP/IP(三)

軟件環境: ubuntu

--------------------------------------------------------------------------------------------------------

最終效果圖:

--------------------------------------------------------------------------------------------------------

注意:此處只有服務端採用了多線程,即可以接收多個客戶端的訪問並進行相互

信。這裏在使用時必須先啓動服務端再啓動客戶端,此時在服務端的左側方框

內會顯示與服務端連接的客戶端名。鼠標點擊你想要通信的客戶名然後在發送消

息即可。

--------------------------------------------------------------------------------------------------------

服務端:

GUI界面設計:

--------------------------------------------------------------------------------------------------------

實現代碼:

非線程部分:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include<QMainWindow>
#include<QtNetwork/QTcpServer>
#include<QStandardItemModel>
#include"socketthread.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    QStandardItemModel *model;

protected:
    void init();
    void newListen();

private:
    Ui::MainWindow *ui;
    QTcpServer *tcpServer;

signals:
   void sendToSocketThrd(QString client,QString datas);

private slots:
    void createSocketThread();
    void revFromThrd(bool isClient,QString datas);
    void removeClient(QString client);
    //void addSocketDescription(int socketdescription);
    //void removeSocketDescription(int socketdescription);
    void on_send_clicked();

    void on_friendlist_clicked(QModelIndex index);
};

#endif // MAINWINDOW_H

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "mainwindow.h"
#include "ui_mainwindow.h"

int Des[256] = {0};
int clientNum = 0;
QString currentClient;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    tcpServer = new QTcpServer;
    model     = new QStandardItemModel();

    model->setColumnCount(2);
    model->setHeaderData(0,Qt::Horizontal,"NAME");
    model->setHeaderData(1,Qt::Horizontal,"IP");

    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(createSocketThread()));

    ui->friendlist->setModel(model);
    ui->friendlist->hideColumn(1);
    ui->friendlist->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);

    ui->friendlist->setEditTriggers(QAbstractItemView::NoEditTriggers);

    newListen();
}

void MainWindow::newListen()
{
    if(!tcpServer->listen(QHostAddress::Any,6666))
    {
        qDebug()<<tcpServer->errorString();
        tcpServer->close();
        return ;
    }
}

void MainWindow::createSocketThread()
{
    socketThread *SThread = new socketThread(tcpServer->nextPendingConnection());

    connect(SThread,SIGNAL(sendToMainWin(bool,QString)),this,SLOT(revFromThrd(bool,QString)));
    connect(SThread,SIGNAL(closeClient(QString)),this,SLOT(removeClient(QString)));
    //connect(SThread,SIGNAL(sendSocketDescription(int)),this,SLOT(addSocketDescription(int)));
    //connect(SThread,SIGNAL(closeSocketDescription(int)),this,SLOT(removeSocketDescription(int)));
    connect(this,SIGNAL(sendToSocketThrd(QString,QString)),SThread,SLOT(revFromMainWin(QString,QString)));

    SThread->start();
}

void MainWindow::on_send_clicked()
{
    QString message;

    message = "SERVER\n"+ui->message->document()->toPlainText();
    ui->message->clear();

    emit sendToSocketThrd(currentClient,message);
}
/*
void MainWindow::addSocketDescription(int socketdescription)
{
    for(int i = 0; i < 256; i++)
    {
        if(Des[i] == 0)
        {
            Des[i] = socketdescription;
            break;
        }
    }
}

void MainWindow::removeSocketDescription(int socketdescription)
{
    for(int i = 0; i < 256; i++)
    {
        if(Des[i] == socketdescription)
        {
            Des[i] = 0;
            break;
        }
    }
}

*/
void MainWindow::revFromThrd(bool isClient,QString datas)
{
    if(isClient)
    {
        QString tmp;
        tmp = QString(strtok(datas.toLatin1().data(),"\n"));
        model->setItem(clientNum,0,new QStandardItem(tmp));
        tmp = QString(strstr(datas.toLatin1().data(),"\n")).mid(1);
        model->setItem(clientNum,1,new QStandardItem(tmp));
        clientNum++;
    }
    else
    {
        ui->displaymessage->append(datas);
    }
}

void MainWindow::removeClient(QString client)
{
    for(int i = 0; i < clientNum;i++)
    {
        if(model->item(i)->text().operator ==(client))
        {
            model->removeRow(i);
            clientNum--;
            break;
        }
    }
}

void MainWindow::on_friendlist_clicked(QModelIndex index)
{
    currentClient = index.data().toString()+"\n";
    currentClient += index.sibling(index.row(),1).data().toString();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

線程部分:

#ifndef SOCKETTHREAD_H
#define SOCKETTHREAD_H

#include<QThread>
#include<QtNetwork/QTcpSocket>
#include<QtNetwork/QHostAddress>

class socketThread : public QThread
{
    Q_OBJECT
public:
    explicit socketThread(QObject *parent = 0);
    socketThread(QTcpSocket *socket);

    QString ip;
    QString clientName;
    bool isClient;
    int  description;

protected:
    void run();

signals:
    void sendToMainWin(bool isClient,QString datas);
    void sendSocketDescription(int socketDescription);
    void closeClient(QString client);

private slots:
    void revFromMainWin(QString client,QString datas);
    void closeSocket();
    void revDatas();

private:
    QTcpSocket * tcpSocket;

};

#endif // SOCKETTHREAD_H
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "socketthread.h"

socketThread::socketThread(QObject *parent) :
    QThread(parent)
{
}

socketThread::socketThread(QTcpSocket *socket)
{
    tcpSocket   = socket;
    isClient    = true;
    description = tcpSocket->socketDescriptor();
    ip          = tcpSocket->peerAddress().toString();

    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(revDatas()));
}

void socketThread::run()
{
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(closeSocket()));
}

void socketThread::revDatas()
{
    if(isClient)
    {
        clientName = tcpSocket->readAll();
        emit sendToMainWin(isClient,clientName+"\n"+ip);
        isClient = false;
    }
    else
    {
        emit sendToMainWin(isClient,clientName+"\n"+tcpSocket->readAll());
    }
}

void socketThread::revFromMainWin(QString client,QString datas)
{
    QString tmp = clientName+"\n"+ip;

    if(tmp.operator ==(client))
    {
        tcpSocket->write(datas.toLatin1().data());
    }
}

void socketThread::closeSocket()
{
    emit closeClient(clientName);
    tcpSocket->close();
}

--------------------------------------------------------------------------------------------------------

服務端:

GUI界面設計:

 

--------------------------------------------------------------------------------------------------------

實現代碼:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QtNetwork>
#include<QtNetwork/QTcpSocket>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    QString myName;

protected:
    void init();
    void newTCPConnect();

private:
    Ui::MainWindow *ui;
    QTcpSocket *tcpSocket;

private slots:
    void revData();
    void sendMyName();
    void displayError(QAbstractSocket::SocketError);
    void on_send_clicked();
};

#endif // MAINWINDOW_H
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    this->tcpSocket = new QTcpSocket(this);

    myName = "PK";

    newTCPConnect();
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(revData()));
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(sendMyName()));
    connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
            this,SLOT(displayError(QAbstractSocket::SocketError)));
}

void MainWindow::revData()
{
    QString datas = tcpSocket->readAll();

    ui->displaymessage->append(datas);
}

void MainWindow::newTCPConnect()
{
    tcpSocket->abort();
    tcpSocket->connectToHost(QHostAddress::Any,6666);
}

void MainWindow::displayError(QAbstractSocket::SocketError)
{
    qDebug()<<tcpSocket->errorString();
    tcpSocket->close();
}

void MainWindow::on_send_clicked()
{
    QString message;

    message = ui->message->document()->toPlainText();

    ui->message->clear();
    tcpSocket->write(message.toLatin1().data());
}

void MainWindow::sendMyName()
{
    tcpSocket->write(myName.toLatin1().data());
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章