Qt实现TCP客户端和服务器通讯程序
复习的心态过一遍之前基础的一些东西,Qt封装了QTcpServer和QTcpSocket两个类,其中QTcpServer继承自QObject,通过listen()函数监听传入的客户端连接,当Client连接上时,QTcpServer会发出newConnection的信号,在对应的槽函数中使用nextPendingConnection()拿到连接的客户端的句柄和信息。
而QTcpSocket则是读写数据的时候使用,过程很简单。
服务器流程:listen->newConnection->nextPendingConnection->readAll/write
客户端流程:connectToHost->waitForConnected->write/readAll
需要注意的是在使用网络相关的类前,需要在pro文件加上QT += network
通信时:
客户端掉线时:
QTcpServer服务器代码(包含.h和.cpp):
.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpServer> #include <QTcpSocket> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); protected slots: void onSendBtnClicked(); void onNewClientConnected(); void onRecvData(); void onClientDisconnected(); private: void Init(); private: Ui::Widget *ui; private: QTcpServer *_tcpServer; QTcpSocket *_tcpSocket; }; #endif // WIDGET_H
.cpp
#include "widget.h" #include "ui_widget.h" #include <QHostAddress> #include <QDebug> #define MyTcpPort 8886 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) ,_tcpServer(nullptr) ,_tcpSocket(nullptr) { ui->setupUi(this); connect(this->ui->btn_send,&QPushButton::clicked,this,&Widget::onSendBtnClicked); Init(); setWindowTitle("服务端"); } Widget::~Widget() { delete ui; if(_tcpSocket) { _tcpSocket->disconnect(); _tcpSocket->abort(); _tcpSocket->close(); _tcpSocket->deleteLater(); } if(_tcpServer) { _tcpServer->close(); delete _tcpServer; } } void Widget::Init() { _tcpSocket = new QTcpSocket; _tcpServer = new QTcpServer; int ret = _tcpServer->listen(QHostAddress::AnyIPv4,MyTcpPort); if(ret==0) { qDebug()<<"_tcpServer->listen is failied"; return; } connect(_tcpServer,&QTcpServer::newConnection,this,&Widget::onNewClientConnected); } void Widget::onSendBtnClicked() { if(!_tcpSocket) return; QString inputText = ui->inputEdit->text(); if(inputText.isEmpty()) return; //发送数据 int ret = _tcpSocket->write(inputText.toStdString().c_str()); if(ret<0) { qDebug()<<"write to client is failed!"; } } void Widget::onNewClientConnected() { if(_tcpServer->hasPendingConnections()) { _tcpSocket = _tcpServer->nextPendingConnection(); if(!_tcpSocket->isValid()) return; connect(_tcpSocket,&QTcpSocket::readyRead,this, &Widget::onRecvData); connect(_tcpSocket,&QTcpSocket::disconnected,this, &Widget::onClientDisconnected); } } void Widget::onRecvData() { if(!_tcpSocket) return; QString recvData=_tcpSocket->readAll(); qDebug()<<"recvData:"<<recvData; this->ui->recvEdit->append(recvData); } void Widget::onClientDisconnected() { QString clientIp = _tcpSocket->peerAddress().toString(); this->ui->recvEdit->append(clientIp+" is Drop line!"); }
QTcpClient客户端代码(包含.h和.cpp):
/.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpSocket> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private: void Init(); protected slots: void onSendBtnClicked(); void onRecvData(); private: Ui::Widget *ui; private: QTcpSocket *_tcpClient; }; #endif // WIDGET_H /.cpp #include "widget.h" #include "ui_widget.h" #define MyTcpPort 8886 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget),_tcpClient(nullptr) { ui->setupUi(this); connect(this->ui->btn_send,&QPushButton::clicked,this,&Widget::onSendBtnClicked); Init(); setWindowTitle("客户端"); } Widget::~Widget() { delete ui; if(_tcpClient) { _tcpClient->close(); _tcpClient->deleteLater(); } } void Widget::Init() { _tcpClient=new QTcpSocket; _tcpClient->abort(); _tcpClient->connectToHost("127.0.0.1",MyTcpPort); if(!_tcpClient->waitForConnected(2000)) { qDebug()<<"connect is failed!"; return; } qDebug()<<"connect is successful"; connect(_tcpClient,&QTcpSocket::readyRead,this,&Widget::onRecvData); } void Widget::onSendBtnClicked() { if(!_tcpClient) return; QString wStr=ui->inputEdit->text(); int ret = _tcpClient->write(wStr.toStdString().c_str()); if(ret<0) { qDebug()<<"send data is failed"; } qDebug()<<"send data is successful!"; } void Widget::onRecvData() { if(!_tcpClient) return; QString recvData= _tcpClient->readAll(); ui->recvEdit->append(recvData); qDebug()<<"recvData:"<<recvData; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)