赞
踩
1. 在.pro工程文件中,加入qt 网络支持
- QT += core gui \
- network
2.创建 ClientSocket 类
客户端的主要功能包括:
连接服务器,断开服务器,接收并显示服务器数据,向服务器发送数据
- //.h
- class ClientSocket : public QTcpSocket
- {
- Q_OBJECT
-
- public:
- explicit ClientSocket(QObject *parent = Q_NULLPTR);
- ~ClientSocket();
-
- bool CilentConect(QHostAddress hadd,ushort port);//连接服务器
- void CilentBreakConect();//断开服务器
- void TransMess(QString str);//向服务器发送数据
-
- signals:
- void dataReady(const QString &ip, const QByteArray &data);//从服务器接收到数据后向界面层发送信号
-
- private slots:
- void recvData();//对QTcpSocket 接收到数据产生的信号设定的槽函数
- };
-
-
- //.cpp
- ClientSocket::ClientSocket(QObject *parent) :QTcpSocket(parent)
- {
- connect(this,SIGNAL(readyRead()),this,SLOT(recvData()));//底层信号readyRead -> 槽函数recvDate
- }
-
- ClientSocket::~ClientSocket()
- {
-
- }
-
-
- bool ClientSocket::CilentConect(QHostAddress hadd,ushort port)
- {
- this->connectToHost(hadd,port);
- if (this->waitForConnected(1000)) // 连接成功则true
- {
- return true;
- }
- return false;
- }
-
- void ClientSocket::CilentBreakConect()
- {
- this->disconnectFromHost();//断开连接
- }
-
- void ClientSocket:: TransMess(QString str)//发送数据
- {
- this->write(str.toLocal8Bit());
- }
-
- void ClientSocket:: recvData() //从服务器接收到数据后
- {
- QString ip = peerAddress().toString().remove(0, 7);
- QByteArray data = readAll();
- emit dataReady(ip, data); //向界面层发送带数据的信号量
- }

3.客户端以及ui设计
- //.h
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- explicit Widget(QWidget *parent = 0);
- ~Widget();
-
- private slots:
- void on_pushButton_Connect_clicked();//连接与断开服务器槽函数
- void on_pushButtonTrans_clicked();//发送数据槽函数
- void recvData(const QString &ip, const QByteArray &data);//接收数据处理槽函数
- private:
- Ui::Widget *ui;
- ClientSocket *Cilent;//客户端Socket类
- };
-
-
- //.cpp
- Widget::Widget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::Widget)
- {
- ui->setupUi(this);
- Cilent = new ClientSocket(parent);
- //客户端类接收到数据的信号连接到界面处理函数
- connect(Cilent, SIGNAL(dataReady(const QString&, const QByteArray&)),this, SLOT(recvData(const QString&, const QByteArray&)));
- }

服务器端程序的主要思路是,创建一个 QTcpServer 来侦听某一个端口,当有客户端接入时,启动一个线程,并创建一个Socket与对应的客户端通讯。所以这里涉及到四个部分:界面类,服务器类,通讯线程处理和服务器Socket。
服务器端及UI设计
- //.h
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- explicit Widget(QWidget *parent = 0);
- ~Widget();
-
- public:
- void showNewConnection(int sockDesc);//提示新连接 sockDesc:客户端ID
- void showDisconnection(int sockDesc);//提示连接断开
-
- signals:
- void MessOk(const QString &mess);
-
- private slots:
- void MessWindUpdate(const QString &mess);
- void on_pushButton_Trans_clicked(); //发送数据按键响应槽函数
- void on_pushButton_StartServer_clicked();//启动或关闭服务器槽函数
-
- signals:
- void sendData(int id, const QByteArray &data); //发送数据产生信号
-
- public slots:
- void recvData(const QString &ip, const QByteArray &data);//接收到数据后的处理槽函数
-
- private:
- Ui::Widget *ui;
- Server *m_Server;
- };
-
- //.c
-
- void Widget::on_pushButton_StartServer_clicked()
- {
- QHostAddress address;
-
- if(ui->pushButton_StartServer->text() == "启动服务器")
- {
- QString localHostName = QHostInfo::localHostName(); //获取主机名
- ui->textBrowser_ServerMess->insertPlainText(localHostName+'\n');
- QHostInfo info = QHostInfo::fromName(localHostName); //获取主机IP
-
- foreach(address,info.addresses())//获取IPV4的第一个ip
- {
- if(address.protocol() == QAbstractSocket::IPv4Protocol)
- {
- ui->textBrowser_ServerMess->insertPlainText(address.toString()+'\n');
- break;
- }
- }
-
- QString serIP = address.toString();//获取IP
- QString serPort = ui->lineEdit_Port->text();//获取端口
-
- m_Server->listen((QHostAddress)serIP,serPort.toUInt());//启动监听
- ui->pushButton_StartServer->setText("关闭服务器");
- }else if(ui->pushButton_StartServer->text() == "关闭服务器")
- {
- m_Server->close();//关闭服务器
- ui->pushButton_StartServer->setText("启动服务器");
- }
-
- }

服务器类:
- //.h
- class Server : public QTcpServer
- {
- Q_OBJECT
- public:
- explicit Server(QObject *parent = Q_NULLPTR);
- ~Server();
-
- private:
- void incomingConnection(int sockDesc); //QTcpServer中被重写的函数,该函数在客户端接入时被调用
-
- private slots:
- void clientDisconnected(int sockDesc); //当产生客户端断开连接时向上层发送信号
-
- private:
- Widget *m_widget; //上层界面的句柄 便于底层 服务器进程类的 信号量直接连接到界面处理函数
-
- QList<int> m_socketList; //服务器Socket ID链表
- };
-
- //.cpp
- //这里的Server类继承于QTcpServer,
- //重写其中的void incomingConnection(int sockDesc)方法,
- //该方法在有客户端接入时自动调用。
- //每当一个新的客户端连接时,通过标识码socketDescriptor,实现与对应的客户端通信
- void Server::incomingConnection(int sockDesc)
- {
- m_socketList.append(sockDesc);//客户端ID 加入链表
-
- ServThread *thread = new ServThread(sockDesc); //创建服务器处理进程
-
- m_widget->showNewConnection(sockDesc); //界面提示,新客户端接入
-
- //服务器进程发出消息,告诉服务器,XX客户端断开连接
- connect(thread, SIGNAL(disconnectTCP(int)), this, SLOT(clientDisconnected(int)));
- //服务器进程发出消息给窗口,从哪个ip收到数据,槽函数由窗口构建
- connect(thread, SIGNAL(dataReady(const QString&, const QByteArray&)),
- m_widget, SLOT(recvData(const QString&, const QByteArray&)));
- //窗口向服务器进程发出信号 以客户端ID 为标识,发出数据,槽函数由服务器进程构建
- connect(m_widget, SIGNAL(sendData(int, const QByteArray&)),
- thread, SLOT(sendDataSlot(int, const QByteArray&)));
- //启动进程
- thread->start();
- }
-
- //这是一个槽函数 用于在界面上显示服务器断开了
- void Server::clientDisconnected(int sockDesc)
- {
- m_widget->showDisconnection(sockDesc);
- }

服务器通讯线程类
- //.h
- class ServThread : public QThread
- {
- Q_OBJECT
- public:
- explicit ServThread(int sockDesc, QObject *parent = Q_NULLPTR);
- ~ServThread();
-
- private:
- void run(void);
-
- public slots:
- void sendDataSlot(int sockDesc, const QByteArray &data);
-
- signals:
- void dataReady(const QString &ip, const QByteArray &data);
- void sendData(int sockDesc, const QByteArray &data);
- void disconnectTCP(int sockDesc);
-
- private slots:
- void recvDataSlot(const QString &ip, const QByteArray &data);
- void disconnectToHost(void);
-
- private:
- ServSocket *m_socket;
-
- int m_sockDesc;
- };
-
- //.c
- void ServThread:: sendDataSlot(int sockDesc, const QByteArray &data)
- {
- emit sendData(sockDesc, data);
- }
-
-
- void ServThread:: recvDataSlot(const QString &ip, const QByteArray &data)
- {
- emit dataReady(ip, data);
- }
-
- void ServThread:: disconnectToHost(void)
- {
- emit disconnectTCP(m_sockDesc);
- m_socket->disconnectFromHost();//断开连接
- this->quit();
- }
-
- void ServThread::run(void)
- {
- m_socket = new ServSocket(m_sockDesc);
-
- if (!m_socket->setSocketDescriptor(m_sockDesc)) {
- return ;
- }
-
- connect(m_socket, &ServSocket::disconnected, this, &ServThread::disconnectToHost);
- connect(m_socket, SIGNAL(dataReady(const QString&, const QByteArray&)),
- this, SLOT(recvDataSlot(const QString&, const QByteArray&)));
- connect(this, SIGNAL(sendData(int, const QByteArray&)),
- m_socket, SLOT(sendData(int, const QByteArray&)));
-
- this->exec();//在Qt中启动消息机制 龟腚
- }
-

服务器Socket类
- //.h
- class ServSocket: public QTcpSocket
- {
- Q_OBJECT
- public:
- explicit ServSocket(int sockDesc, QObject *parent = Q_NULLPTR);
- ~ServSocket();
-
- signals:
- void dataReady(const QString &ip, const QByteArray &data);
-
- public slots:
- void recvData(void);
- void sendData(int id, const QByteArray &data);
-
- private:
- int m_sockDesc;
- };
-
- //.c
- ServSocket::ServSocket(int sockDesc,QObject *parent) :QTcpSocket(parent)
- {
- m_sockDesc = sockDesc;
- connect(this,SIGNAL(readyRead()),this,SLOT(recvData()));//底层信号readyRead -> recvDate
- }
-
- ServSocket::~ServSocket()
- {
-
- }
-
-
- void ServSocket:: recvData()
- {
- QString ip = peerAddress().toString().remove(0, 7);
- QByteArray data = readAll();
- emit dataReady(ip, data);
- }
-
- void ServSocket:: sendData(int id, const QByteArray &data)
- {
- if (id == m_sockDesc && !data.isEmpty()) {
- this->write(data);
- }
- }

源码下载链接
https://download.csdn.net/download/zhaopeng6b/14193041
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。