1. 程式人生 > >QT中 實現一個服務端接收兩個客戶端的解決方法

QT中 實現一個服務端接收兩個客戶端的解決方法

最近自己在折騰QT中實現TCP服務端的過程中,發現以往的例子都是點對點的,也就是說大都是一個客戶端,一個服務端,然後兩個進行通訊,而對於單個服務端與多個客戶端的通訊,非常稀少,找到一個但對於我們新手來說,有點複雜,不好理解,下面我介紹一個新手也能明白的一種解決方案。

下面是mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButton_listen_clicked();

    void on_pushButton_send_clicked();

    void ClientReadData(/*int clientID,QString IP,int Port,QByteArray data*/);


    void server_New_Connect();

    void socket_Read_Data();

    void socket2_Read_Data();

    void socket_Disconnected();

private:
    Ui::MainWindow *ui;
    QTcpServer* server;
    QTcpSocket* socket;
    QTcpSocket* socket2;
};

#endif // MAINWINDOW_H

下面是main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
下面是mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>
int Connect_Num=0;

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

    ui->lineEdit_port->setText("5000");  //初始化
 //   ui->lineEdit_port_two->setText("1234");  //初始化
    ui->pushButton_send->setEnabled(false);

    server = new QTcpServer();
    connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);//前面是訊號,後面是槽函式
  //  connect(server,&QTcpServer::newConnection,this,&MainWindow::ClientReadData);
}//SIGNAL(ClientReadData(int,QString,int,QByteArray))

MainWindow::~MainWindow()
{
    server->close();
    server->deleteLater();
    delete ui;
}




void MainWindow::on_pushButton_listen_clicked()
{
    if(ui->pushButton_listen->text() == tr("偵聽"))
    {
        //從輸入框獲取埠號
        int port = ui->lineEdit_port->text().toInt();
      //  int port1 = ui->lineEdit_port_two->text().toInt();

        //監聽指定的埠
        if(!server->listen(QHostAddress::Any, port))
        {
            //若出錯,則輸出錯誤資訊
            qDebug()<<server->errorString();
            return;
        }
     //   if(!server->listen(QHostAddress::Any, port1))
      //  {
            //若出錯,則輸出錯誤資訊
      //      qDebug()<<server->errorString();
      ///      return;
      //  }
        //修改按鍵文字
        ui->pushButton_listen->setText("取消偵聽");
        qDebug()<< "Listen succeessfully!";
    }
    else
    {
        //如果正在連線(點選偵聽後立即取消偵聽,若socket沒有指定物件會有異常,應修正——2017.9.30)
        if(socket->state() == QAbstractSocket::ConnectedState)
        {
            //關閉連線
            socket->disconnectFromHost();
        }
        //取消偵聽
        server->close();
        //修改按鍵文字
        ui->pushButton_listen->setText("偵聽");
        //傳送按鍵失能
        ui->pushButton_send->setEnabled(false);
    }
}

void MainWindow::on_pushButton_send_clicked()
{
    qDebug() << "Send: " << ui->textEdit_send->toPlainText();
    //獲取文字框內容並以ASCII碼形式傳送
    socket->write(ui->textEdit_send->toPlainText().toLatin1());
    socket->flush();
}
void MainWindow::ClientReadData(/*int clientID,QString IP,int Port,QByteArray data*/)
{
    ui->textEdit_recv_two->setText("使用者已上線");

}
void MainWindow::server_New_Connect()//沒接入一個都會響應一次
{
    ui->pushButton_send->setEnabled(true);//傳送鍵使能
    //獲取客戶端連線
    Connect_Num++;
    if(Connect_Num==1)
    {
        socket = server->nextPendingConnection();//建立一個連線
        QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);//前面是訊號 後面是槽函式
        QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
        qDebug() << "A Client connect!";

    }
   // socket = server->nextPendingConnection();
    //連線QTcpSocket的訊號槽,以讀取新資料
  //  QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);//前面是訊號 後面是槽函式
   // QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
    //傳送按鍵使能
    if(Connect_Num==2)
    {
        socket2 = server->nextPendingConnection();//建立一個新連線
        QObject::connect(socket2, &QTcpSocket::readyRead, this, &MainWindow::socket2_Read_Data);//前面是訊號 後面是槽函式
        QObject::connect(socket2, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
        qDebug() << "B Client connect!";
    }
   // qDebug() << "A Client connect!";
}

void MainWindow::socket_Read_Data()
{
    QByteArray buffer;
    //讀取緩衝區資料
    buffer = socket->readAll();
    if(!buffer.isEmpty())
    {
        QString str = ui->textEdit_recv->toPlainText();
        str+=tr(buffer);
        //重新整理顯示
        ui->textEdit_recv->setText(str);
    }
}

void MainWindow::socket2_Read_Data()
{
    QByteArray buffer;
    //讀取緩衝區資料
    buffer = socket2->readAll();
    if(!buffer.isEmpty())
    {
        QString str = ui->textEdit_recv_two->toPlainText();
        str+=tr(buffer);
        //重新整理顯示
        ui->textEdit_recv_two->setText(str);
    }
}
void MainWindow::socket_Disconnected()
{
    //傳送按鍵失能
    ui->pushButton_send->setEnabled(false);
    qDebug() << "Disconnected!";
}
下面是介面檔案

主要的是下面這個方法

server_New_Connect() 與newConnection 這個訊號連線,而這個訊號一旦有客戶端連線上就會響應一次,而響應一次就在server_New_Connect()這個方法裡面+1,
然後與相應的客戶端建立連線
Connect_Num=1的與對應的連線   Connect_Num=2的與對應的連線 
一旦連線上,就只要在和對應的讀資料方法相連線,就可以做到兩個連線互不干擾。 格式不好 湊活著看哈 請多包涵  有問題可以留言