qt学习_网络编程_tcp通信聊天(代码片段)

LeslieX徐 LeslieX徐     2023-01-16     374

关键词:

网络编程

TCP通信

1.用到的类

  • QTcpServer
公共函数:

void 				close ()
QString 		errorString () const
bool 				isListening () const
bool 				listen ( const QHostAddress & address = QHostAddress::Any, quint16 port = 0 )
QHostAddress 	serverAddress () const
quint16 		serverPort () const
bool 				waitForNewConnection ( int msec = 0, bool * timedOut = 0 )

virtual QTcpSocket * 	nextPendingConnection ()

信号:
void 		newConnection()

version5:
void 		acceptError(QAbstractSocket::SocketError socketError)



保护函数:

void 				addPendingConnection ( QTcpSocket * socket )
virtual void 	incomingConnection ( int socketDescriptor )


  • QAbstractSocket
参数:

enum NetworkLayerProtocol  IPv4Protocol, IPv6Protocol, UnknownNetworkLayerProtocol 
enum SocketError  ConnectionRefusedError, RemoteHostClosedError, HostNotFoundError, SocketAccessError, ..., UnknownSocketError 
enum SocketOption  LowDelayOption, KeepAliveOption, MulticastTtlOption, MulticastLoopbackOption 
enum SocketState  UnconnectedState, HostLookupState, ConnectingState, ConnectedState, ..., ListeningState 
enum SocketType  TcpSocket, UdpSocket, UnknownSocketType 


公共函数:

QAbstractSocket ( SocketType socketType, QObject * parent )

void 		abort ()
void 		connectToHost ( const QString & hostName, quint16 port, OpenMode openMode = ReadWrite )
void 		connectToHost ( const QHostAddress & address, quint16 port, OpenMode openMode = ReadWrite )
void 		disconnectFromHost ()

bool 		waitForConnected ( int msecs = 30000 )
bool 		waitForDisconnected ( int msecs = 30000 )

QHostAddress 	localAddress () const
quint16 			localPort () const
QHostAddress 	peerAddress () const
QString 			peerName () const
quint16 			peerPort () const

虚函数:
virtual qint64 	bytesAvailable () const
virtual qint64 	bytesToWrite () const
virtual bool 		canReadLine () const


信号:

void 		connected ()
void 		disconnected ()
void 		error ( QAbstractSocket::SocketError socketError )
void 		hostFound ()
void 		stateChanged ( QAbstractSocket::SocketState socketState )

继承的QIODevice信号:
void readyRead()

界面

服务器端

1.主窗口定义和构造函数
MainWindow.h:
定义私有变量tcpServer建立TCP服务器,定义tcpSocket用于与客户端进行socket连接和通信。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostInfo>

namespace Ui 
class MainWindow;


class MainWindow : public QMainWindow

    Q_OBJECT
private:
    QLabel *LabListen;
    QLabel *LabSocketState;
    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;
    QString getLocalIP();

protected:
    void closeEvent(QCloseEvent *event);
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void onNewConnection();//对应QTcpServer的newConnect信号
    void onSocketStateChange(QAbstractSocket::SocketState socketState);
    void onClientConnected();
    void onClientDisconnected();
    void onSocketReadyRead();//读取socket传入的数据

    void on_actStart_triggered();
    void on_actStop_triggered();
    void on_actClear_triggered();
    void on_actExit_triggered();
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
;

#endif // MAINWINDOW_H

构造函数:

QString MainWindow::getLocalIP()

    QString hostName = QHostInfo::localHostName();//得到本地主机名
    QHostInfo hostInfo = QHostInfo::fromName(hostName);//根据主机名获得信息
    QString localIP = "";
    QList<QHostAddress> addList = hostInfo.addresses();//获得信息中的IP地址序列

    if(!addList.isEmpty())
    for (int i=0;i<addList.count();++i) 
            QHostAddress aHost = addList.at(i);
            if(QAbstractSocket::IPv4Protocol == aHost.protocol())
            
                localIP = aHost.toString();
                break;
            
     
    return localIP;


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);

    //状态栏设置
    LabListen = new QLabel("listen state: ");
    LabListen->setMinimumWidth(150);
    ui->statusBar->addWidget(LabListen);

    LabSocketState = new QLabel("socket state: ");
    LabSocketState->setMinimumWidth(200);
    ui->statusBar->addWidget(LabSocketState);

    //标题栏设置
    QString localIP = getLocalIP();
    this->setWindowTitle(this->windowTitle() + "----localIP: " + localIP);
    ui->comboBox->addItem(localIP);
    tcpServer = new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),
            this,SLOT(onNewConnection()));

2.网络监听与socket建立
监听开始和停止:

void MainWindow::on_actStart_triggered()

    //start listening
    QString IP = ui->comboBox->currentText();
    qint16 port = ui->spinBox->value();
    QHostAddress addr(IP);

    tcpServer->listen(addr,port);//监听指定地址和端口
    //tcpServer->listen(QHostAddress::Any,port);

    ui->plainTextEdit->appendPlainText("**start listening...");
    ui->plainTextEdit->appendPlainText("**server Addr: " +
                                 tcpServer->serverAddress().toString());
    ui->plainTextEdit->appendPlainText("**server port: " +
                                 QString::number(tcpServer->serverPort()));
    ui->actStart->setEnabled(false);
    ui->actStop->setEnabled(true);
    LabListen->setText("listen state: listening");


void MainWindow::on_actStop_triggered()
//停止监听
    if(tcpServer->isListening())
    
        tcpServer->close();//停止监听
        ui->actStart->setEnabled(true);
        ui->actStop->setEnabled(false);
        LabListen->setText("Listing state: stop");
    



socket建立与连接

void MainWindow::onNewConnection()

    tcpSocket = tcpServer->nextPendingConnection();

    connect(tcpSocket, SIGNAL(connected()),
            this, SLOT(onClientConnected()));
    
    connect(tcpSocket,SIGNAL(disconnected()),
            this, SLOT(onClientDisconnected()));
            
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    
    connect(tcpSocket,SIGNAL(readyRead()),
            this, SLOT(onSocketReadyRead()));


void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
//socket状态变化时
    switch (socketState) 
    case QAbstractSocket::UnconnectedState:
        LabSocketState->setText("socket state: UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        LabSocketState->setText("socket state: HostLookupState");
        break;
    case QAbstractSocket::ConnectingState:
        LabSocketState->setText("socket state: ConnectingState");
        break;
    case QAbstractSocket::BoundState:
        LabSocketState->setText("socket state: BoundState");
        break;
    case QAbstractSocket::ClosingState:
        LabSocketState->setText("socket state: ClosingState");
        break;
    case QAbstractSocket::ListeningState:
        LabSocketState->setText("socket state: ListeningState");
        break;
    case QAbstractSocket::ConnectedState:
        LabSocketState->setText("socket state: ConnectedState");
        break;
    


void MainWindow::onClientConnected()
//客户接入时
    ui->plainTextEdit->appendPlainText("**client socket connected");
    ui->plainTextEdit->appendPlainText("**peer address: " +
                                       tcpSocket->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("**peer port: " +
                                       QString::number(tcpSocket->peerPort()));


void MainWindow::onClientDisconnected()
//客户断开连接时
    ui->plainTextEdit->appendPlainText("**client socket disconnected");
    tcpSocket->deleteLater();

3.与客户端通信

//读取
void MainWindow::onSocketReadyRead()
//数据通信
    //读取缓冲区行文本
    //canReadLine判断是否有新的一行数据需要读取
    //再用readLine函数读取一行数据
    while(tcpSocket->canReadLine())
        ui->plainTextEdit->appendPlainText("[receive] " +
                                           tcpSocket->readLine());


//发送
void MainWindow::on_pushButton_clicked()
//发送一行字符串,以换行符结束
    QString msg = ui->lineEdit->text();
    ui->plainTextEdit->appendPlainText("[send] "+msg);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();//让键盘继续在lineedit框内

    QByteArray str = msg.toUtf8();
    str.append('\\n');
    tcpSocket->write(str);

客户端

1.主窗口定义和构造函数
主窗口定义:
客户端只使用一个QTcpSocket对象

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QLabel>
#include <QHostInfo>

namespace Ui 
class MainWindow;


class MainWindow : public QMainWindow

    Q_OBJECT
private:
    QTcpSocket *tcpClient;
    QLabel *LabSocketState;
    QString getLocalIP();
protected:
    void closeEvent(QCloseEvent *event);
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void onConnected();
    void onDisconnected();
    void onSocketStateChange(QAbstractSocket::SocketState socketState);
    void onSocketReadyRead();
    
    void on_actLink_triggered();
    void on_actunLink_triggered();
    void on_pushButton_clicked();
    void on_actQuit_triggered();
    void on_actClear_triggered();

private:
    Ui::MainWindow *ui;
;

#endif // MAINWINDOW_H

构造函数:
主要功能:创建tcpClient,并建立信号与槽函数的关联


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);

    //设置套接字
    tcpClient = new QTcpSocket(this);

    //设置状态栏
    LabSocketState = new QLabel("socket state:");
    LabSocketState->setMinimumWidth(250);
    ui->statusBar->addWidget(LabSocketState);
    //获得本机地址,设置标题栏
    QString localIP = getLocalIP();
    this->setWindowTitle(this->windowTitle()+
                         "localIP: "+localIP);
    ui->comboBox->addItem(localIP);

    //链接信号
    connect(tcpClient, SIGNAL(connected()),
            this, SLOT(onConnected()));
    connect(tcpClient, SIGNAL(disconnected()),
            this, SLOT(onDisconnected()));
    connect(tcpClient, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    connect(tcpClient, SIGNAL(readyRead()),
            this, SLOT(onSocketReadyRead()));


2.建立连接
建立连接按钮:

void MainWindow::on_actLink_triggered()
//连接到服务器
    QString addr = ui->comboBox->currentText();
    quint16 port = ui->spinBox->value();
    tcpClient->connectToHost(addr,port);


void MainWindow::on_actunLink_triggered()
//断开连接
    if(tcpClient->state()==QAbstractSocket::ConnectedState)
        tcpClient->disconnectFromHost();

接受连接信号的槽函数:

void MainWindow::onConnected()

    ui->plainTextEdit->appendPlainText("**server connected...");
    ui->plainTextEdit->appendPlainText("**peer Addr: " +
                                 tcpClient->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("**peer port: " +
                                 QString::number(tcpClient->peerPort()));
    ui->actLink->setEnabled(false);
    ui->actunLink->setEnabled(true);


void MainWindow::onDisconnected()

    ui->plainTextEdit->appendPlainText("**server disconnected");
    ui->actLink->setEnabled(true);
    ui->actunLink->setEnabled(false);

3.与服务器数据收发
采用基于行的数据通信协议

void MainWindow::on_pushButton_clicked()

    QString msg = ui->lineEdit->text();
    ui->plainTextEdit->appendPlainText("[send] "+msg);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();//让键盘继续在lineedit框内

    QByteArray str = msg.toUtf8();
    str.append('\\n');
    tcpClient->write(str);


void MainWindow::onSocketReadyRead()

    while(tcpClient->canReadLine())
            ui->plainTextEdit->appendPlainText("[receive] " +
                                               tcpClient->readLine());

代码总结

服务器和客户端的MainWindow.cpp代码
1.TCP_Server代码

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

QString MainWindow::getLocalIP()

    QString hostName = QHostInfo::localHostName();//得到本地主机名
    QHostInfo hostInfo = QHostInfo::fromName(hostName);//根据主机名获得信息
    QString localIP = "";
    QList<QHostAddress> addList = hostInfo.addresses();//获得信息中的IP地址序列

    if(!addList.isEmpty查看详情  

开源应用qt—tcp网络上位机的设计(代码片段)

...“设计目标”下图所示),可以和STM32、Adruino等通信实现无线局域网控制系统。本文的通信内容和图表内容可以参考作者之前的文章STM32+ESP8266连接电脑Qt网络上位机——QT篇https://blog.csdn.net/qq_53734051/article/details/126706759... 查看详情

linux应用学习_网络开发(代码片段)

Linux应用学习_网络开发1.TCP套接字编程1.1套接字1.1.1通用套接字sockaddrstructsockaddrsa_family_tsa_family; /*addressfamily,AF_xxx*/charsa_data[14];/*14bytesofprotocoladdress*/;typedef 查看详情

socket之简单的unity3d聊天室__tcp协议(代码片段)

服务器端程序1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Linq;4usingSystem.Net;5usingSystem.Net.Sockets;6usingSystem.Text;7usingSystem.Threading.Tasks;8namespace聊天室_服务器端_TCP910classProgram11 查看详情

9.0.网络编程_io通信模型(代码片段)

5.IO通信模型  网络通信的本质是网络间的数据IO。只要有IO,就会有阻塞或非阻塞的问题,无论这个IO是网络的,还是硬盘的。原因在于程序是运行在系统之上的,任何形式的IO操作发起都需要系统的支持  使用套接字建立TCP... 查看详情

计算机网络原理学习笔记_简要总结(代码片段)

本文目录CS架构与BS架构网络通信OSI七层协议/网络七层协议简单理解版本,五层协议对数据链路层的一点补充对网络层的一点补充对传输层的一点补充三次握手建立链接四次挥手断开链接tcp协议的半连接池对应用层的一点补... 查看详情

java期末考试试题及参考答案(13)(代码片段)

..._____、________、________。2.传输层主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议ÿ 查看详情

qt学习_qgraphics进阶学习笔记(代码片段)

QGraphics进阶学习1.保存图片函数QPixmapQWidget::grab(constQRect&rectangle=QRect(QPoint(0,0),QSize(-1,-1)))Rendersthewidgetintoapixmaprestrictedbythegivenrectangle.Ifthewidgethasanychildren,thentheyareals 查看详情

freecplus框架-tcp网络通信(代码片段)

...eecplus.net)下载。本文介绍的是freecplus框架的TCP/IP协议网络通信的函数和类。函数和类的声明文件是freecplus/_freecplus.h。函数和类的定义文件是freecplus/_freecplus.cpp。示例程序位于freecplus/demo目录中。编译规则文件是freecplus/demo/makefile... 查看详情

026.3网络编程tcp聊天(代码片段)

分为客户端和服务端,分别进行收发操作##########################################################################客户端:###思路:1、建立tcp客户端服务   1.1因为是面向连接,必须有连接才有通信   1.2在创建客户端时,就... 查看详情

qt学习_qt远程文件升级(代码片段)

QT文档升级首先写配置文件:[update]filename="D:\\\\lesliex\\\\QTpro\\\\UpdatePro\\\\testupdatefile\\\\file";checkname="file";代码选择已更新的文件夹voidMainWindow::on_pushButton_clicked()update 查看详情

qt学习_qlistview使用(代码片段)

QListView使用创建一个QStringList创建一个QStringListModelQStringListstr;QStringListModelstrMod;strMod.setStringList(str);设置QListViewQListViewview;view.setModel(strMod);QListView的增删增://列表末尾添加项strMod.insert 查看详情

qt学习_menu菜单(代码片段)

Menu菜单voidWidget::MenuRequested(QPointp)QMenu*menu=newQMenu(this);menu->setAttribute(Qt::WA_DeleteOnClose);menu->addAction("resize",this,[=]()ui->cw->rescaleAxes();ui->c 查看详情

qt学习_qt实现拖拽功能(代码片段)

QT实现拖拽功能重写两个虚函数voiddragEnterEvent(QDragEnterEvent*event);voiddropEvent(QDropEvent*event);例子voidMainWindow::dragEnterEvent(QDragEnterEvent*event)if(event->mimeData()->hasUrls())//若是文件路径则允许拖拽eve 查看详情

qt学习_qt图形视图(代码片段)

QT图形视图框架GraphicsView一、主要特点系统可以利用openGL工具改善绘图性能支持事件传播体系结构通过二元空间划分树提供快速的图元查找二、三元素场景类(QGraphicsScene):用于放置图元的容器,本身不可见,需要搭配... 查看详情

qt学习_mvc框架(代码片段)

MVC框架#include<QAbstractItemView>#include<QAbstractItemModel>#include<QDirModel>#include<QTreeView>#include<QListView>#include<QTableView>#include<QSplitter>#i 查看详情

qt学习_qt调用cmd指令(代码片段)

QT调用Windows的cmd指令知识点QProcess进程的使用process.start(程序,参数指令)process.waitForStarted()process.waitForFinished()process.close()cmd指令的使用cmd/c指令功能运行选择的程序获取选择程序的pid通过taskkill关闭程序进程开启程序voidMainWind... 查看详情

qt学习_qgraphics进阶学习笔记(代码片段)

QGraphics进阶学习1.保存图片函数QPixmapQWidget::grab(constQRect&rectangle=QRect(QPoint(0,0),QSize(-1,-1)))Rendersthewidgetintoapixmaprestrictedbythegivenrectangle.Ifthewidgethasanychildren,thentheyarealsopaintedintheappropriatepositions.Ifarectanglewithaninvalidsizeisspecified(thede... 查看详情