第10章:TcpServer

1,TCP服务端

2,源码:

#ifndef SERVER_H
#define SERVER_H
#include <QObject>
#include <QTcpServer>
#include <QList>
#include "tcpclientsocket.h"

class Server : public QTcpServer
{
    Q_OBJECT

public:
    Server(QObject *parent = 0, int port = 0);
    QList<TcpClientSocket *> tcpClientSocketList;                       //用来保存与每一个客户端连接的TcpClientSocket;

signals:
    void updateServer(QString, int);

public slots:
    void updateClients(QString, int);
    void slotDisconnected(int);

protected:
    void incomingConnection(int socketDescriptor);
};

#endif // SERVER_H
#include "server.h"

Server::Server(QObject *parent, int port) :QTcpServer(parent)
{
    //QHostAddress::Null                       //表示一个空地址
    //QHostAddress::LocalHost                  //表示本地地址
    //QHostAddress::Broadcast                  //表示广播地址255,255,255,255
    //QHostAddress::Any                        //表示IPV4的任意地址0.0.0.0
    //QHostAddress::AnyIPv6                    //表示IPV6的任意地址

    listen(QHostAddress::Any, port);           //在指定的端口对任意地址进行监听
}

//当出现一个新的连接是,QTcpServer触发该函数,参数socketDescriptor指定了连接socket的描述符
void Server::incomingConnection(int socketDescriptor)
{
    //创建一个新的TcpClientSocket与客户端通信
    TcpClientSocket *tcpClientSocket = new TcpClientSocket(this);

    //连接TcpClientSocket的updateClients信号
    connect(tcpClientSocket, SIGNAL(updateClients(QString,int)), this, SLOT(updateClients(QString,int)));

    //连接TcpClientSocket的disconnected信号
    connect(tcpClientSocket, SIGNAL(disconnected(int)), this, SLOT(slotDisconnected(int)));

    //将新创建的TcpClientSocket的套接字描述符指定为参数
    tcpClientSocket->setSocketDescriptor(socketDescriptor);

    tcpClientSocketList.append(tcpClientSocket);
}



//将任意客户端发来的信息进行广播,保证聊天室的所有客户均能看到其他人的发言
void Server::updateClients(QString msg, int length)
{
    //发送updateServer信号,用来通知服务器对话框跟新相应的显示状态
    emit updateServer(msg, length);

    //实现信息的广播
    for(int i=0; i<tcpClientSocketList.count(); i++)
    {
        QTcpSocket *item = tcpClientSocketList.at(i);
        QString str = "Admin: Receive";
        if (item->write(str.toLatin1(), str.length()) != length)
        {
            continue;
        }
    }
}



//断开TcpClientSocket对象删除的功能
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;
}
#ifndef TCPCLIENTSOCKET_H
#define TCPCLIENTSOCKET_H

#include <QObject>
#include <QTcpSocket>

class TcpClientSocket : public QTcpSocket
{
    Q_OBJECT                                                        //创建信号和槽的关系

public:
    TcpClientSocket(QObject *parent = 0);

signals:
    void updateClients(QString, int);
    void disconnected(int);

protected slots:
    void dateReceived();
    void slotDiscoonected();
};

#endif // TCPCLIENTSOCKET_H
#include "tcpclientsocket.h"

//建立关联
TcpClientSocket::TcpClientSocket(QObject *parent):QTcpSocket(parent)
{
    connect(this, SIGNAL(readyRead()), this, SLOT(dateReceived()));

    connect(this, SIGNAL(disconnected()), this, SLOT(slotDiscoonected()));
}


//数据接收
void TcpClientSocket::dateReceived()
{
    while(bytesAvailable() > 0)
    {
        int length = bytesAvailable();
        char buf[1024];
        read(buf, length);

        QString msg = buf;
        emit updateClients(msg, length);
    }
}


// 断开连接
void TcpClientSocket::slotDiscoonected()
{
    emit disconnected(this->socketDescriptor());
}
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    port = 5555;
    ui->lineEdit->setText(QString::number(port));
}

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



//创建聊天室
void MainWindow::on_pushButton_clicked()
{
    server = new Server(this, port);
    connect(server, SIGNAL(updateServer(QString,int)), this, SLOT(updateServer(QString,int)));
    ui->pushButton->setEnabled(false);
}


//用于更新服务器上的信息显示
void MainWindow::updateServer(QString msg, int length)
{
    ui->listWidget->addItem(msg.left(length));
}

3,效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ksmtnsv37297/article/details/86623245