资讯详情

Qt ---- QTcpSocket 编程

📅 2026/10/27 18:50:22 | 华诺云谱 👁 阅读
Qt ---- QTcpSocket 编程
传输控制协议 transmission control protocol TCP是一种被大多数 Internet 网络协议用于数据传输的底层网络协议它是可靠的、面向流和连接的传输协议特别适合用于连续数据传输。TCP 通信必须先建立 TCP 连接通信端分为客户端和服务器端。 服务器端程序必须用 QTcpServer 进行端口监听建立服务器使用 QTcpSocket 建立连接然后使用套接字进行通信。1 服务器端Server服务器程序首先需要用函数 listen() 开始服务器端监听可以设置监听本地的 IP 地址和端口一般一个服务器端程序只监听某个端口的网络连接。当有一个新的连接可用时QTcpServer 内部调用incomingConnection() 函数创建一个QTcpSocket 对象将其添加到内部可用新连接列表然后发射 newConnection() 信号。在newConnection() 的槽函数中使用nextPendingConnection() 获取新连接在客户端与服务器端建立 TCP 连接后具体的数据通信是通过 QTcpSocket 对象完成的。头文件*.hclass MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent 0); ~MainWindow(); private: Ui::MainWindow *ui; QTcpServer *m_tcpServer; QTcpSocket *m_tcpSocket; private slots: void newConnection(); void tcpReceive(); void tcpDisconnected(); };源文件*.cppMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { // ui-setupUi(this); m_tcpServer new QTcpServer; if(m_tcpServer.listen(QHostAddress(192.168.0.10),1340)) { qDebug() QString(监听成功); }else{ qDebug() QString(监听失败); } connect(m_tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection())); } void MainWindow::newConnection()//new link { m_tcpSocket m_tcpServer-nextPendingConnection(); //get socket connect(m_tcpSocket,SIGNAL(readyRead()),this,SLOT(tcpReceive())); connect(m_tcpSocket,SIGNAL(disconnected()),this,SLOT(tcpDisconnected())); m_tcpSocket-write(QString(link Success).toUtf8());//write char* or QByteArray m_tcpSocket-flush(); //clear buffer, trans immediately } void MainWindow::tcpReceive() { QStringList rec;//基于行,字符串 while(m_tcpSocket-canReadLine()) { rec.append(m_tcpSocket-readLine()); } // QByteArray ba; // while(m_tcpSocket-bytesAvailable())//基于块,二进制,组帧发送数据一般用于设备间通信 // { // ba.append(m_tcpSocket-readAll()); // } // struct{ // uint frameHead; // uint framdId; // uint dataLength; // }aFrame; // memcpy(aFrame,ba.data(),sizeof(aFrame)); } void MainWindow::tcpDisconnected() { qDebug() QString(断开连接); } MainWindow::~MainWindow() { if(m_tcpServer-isListening()) m_tcpServer-close(); //stop listen }QTcpServer 主要用于在服务器端进行网络监听创建网络 socket 连接。 QTcpServer 的父类是 QObject。QTcpServer的主要接口函数类型函数功能公有函数void close()关闭服务器停止网络监听bool listen()监听设置的IP地址(本地)和端口(本地)若成功返回true监听端口范围 1024~49151bool isListening()是否处于监听状态QTcpSocket *nextPendingConnection()返回下一个等待接入的连接获取socket指针quint16 serverPort()返回服务器监听的端口boolwaitForNewConnection()以阻塞方式等待新的连接信号void acceptError()接收到一个新的连接新连接发生错误时信号发射void newConnection()当有新的连接时信号发射保护函数void incomingConnection()当有一个新的连接可用时QTcpServer 内部调用此函数创建一个QTcpSocket 对象将其添加到内部可用新连接列表然后发射 newConnection() 信号void addPendingConnection()由 incomingConnection() 调用将创建的 QTcpSocket 添加到内部可用新连接列表个人理解保护函数和私有函数是类内部的具体实现不会开放给客户程序员。在编写程序时一般也不会用到。由于 QTcpSocket除了构造函数和析构函数 QTcpSocket 类的其他函数都是从其父类 QAbstractSocket 继承或重定义的。QAbstractSocket 用于 TCP 的主要接口函数类型函数功能公有函数voidconnectToHost()以异步方式连接到指定 IP 地址和端口的 TCP 服务器连接成功后会发射 connected() 信号voiddisconnectFromHost()断开 socket 连接成功断开后会发射 disconnected() 信号void close()关闭 socket 的 I/O 设备会自动调用 disconnectFromHost()boolwaitForConnected()等待建立 socket 连接可设置等待时间默认30sbool waitForDisconnected()等待断开 socket 连接可设置等待时间默认30sQHostAddress localAddress()返回当前 socket 的地址quint16 localPort()返回当前 socket 的端口QString peerName()返回对方 socket 的地址quint16 peerPort()返回对方 socket 的端口qint64 readBufferSize()返回内部读取缓冲区的大小该值决定了 read() 和 readAll() 函数能读出数据的大小void setReadBufferSize()设置内部读取缓冲区的大小qint64bytesAvailable()返回读取缓冲区中数据的字节数boolcanReadLine()是否有一行数据要从 socket 缓冲区读取QAbstractSocket::SocketStatestate()返回 socket 连接状态信号voidconnected()connectToHost() 成功连接到服务器时发射voiddisconnected()断开连接时发射void errorOccurred()socket 发生错误时发射void hostFound()connectToHost() 找到主机时发射voidstateChanged()socket 连接状态变化时发射voidreadyRead()缓冲区有新数据需要读取时发射。该信号为父类QIODevice 中定义的一个信号2 客户端Client客户端的 QTcpSocket 对象首先通过connectToHost(服务器ip,服务器port) 尝试连接到服务器该函数需要指定服务器的 IP 地址和端口。以异步方式连接到服务器不会阻塞程序运行成功连接后 QTcpSocket 对象会发射connected() 信号。如果需要使用阻塞方式连接到服务器端则使用函数waitForConnected() 阻塞程序运行直到连接成功或失败可设置尝试连接的时间。客户端和服务器端建立连接后 各自的 QTcpSocket 对象可以向缓冲区写数据或读取数据 实现数据通信。 当缓冲区有新数据进入时 QTcpSocket 对象会发射readyRead()信号在该信号的槽函数里读取缓冲区数据。socket 之间的数据通信协议一般有两种——基于行的或基于块的。基于行的数据通信协议一般用于纯文本数据的通信每一行数据以一个换行符结束。函数canReadLine()判断是否有新的一行数据需要读取如果有就可以用函数readLine()读取一行数据。基于块的数据通信协议一般用于二进制数据的传输需要自定义具体的格式。函数bytesAvailable()判断是否有新的一块数据需要读取如果有就可以用函数readAll()读取所有数据。基于行的发送数据为QByteArray直接将 QString().toUtf8() 转换为 QByteArray常用于文本传输基于块的发送数据为 char*使用 memcpy 将数据内存到 char 内存上常用于设备间的数据传输。头文件*.hclass MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent 0); ~MainWindow(); private: Ui::MainWindow *ui; QTcpSocket *m_tcpSocket; private slots: void tcpReceive();//receive buffer data void tcpConnected(); void tcpDisconnected(); };源文件*.cppMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { // ui-setupUi(this); m_tcpSocket new QTcpSocket; connect(m_tcpSocket,SIGNAL(readyRead()),this,SLOT(tcpReceive())); connect(m_tcpSocket,SIGNAL(connected()),this,SLOT(tcpConnected())); connect(m_tcpSocket,SIGNAL(disconnected()),this,SLOT(tcpDisconnected())); m_tcpSocket-connectToHost(192.168.0.10,1340); if(!m_tcpSocket-waitForConnected(100)) { qDebug() QString(连接失败); } } MainWindow::~MainWindow() { // delete ui; if(m_tcpSocket-state()QTcpSocket::ConnectedState) m_tcpSocket-disconnectFromHost(); } void MainWindow::tcpReceive() { //rec text data QStringList rec;//基于行,字符串 while(m_tcpSocket-canReadLine()) { rec.append(m_tcpSocket-readLine()); } //rec binary // QByteArray ba; // while(m_tcpSocket-bytesAvailable())//基于块,二进制,组帧发送数据一般用于设备间通信 // { // ba.append(m_tcpSocket-readAll()); // } // struct{ // uint frameHead; // uint framdId; // uint dataLength; // }aFrame; // memcpy(aFrame,ba.data(),sizeof(aFrame)); } void MainWindow::tcpConnected() { qDebug() QString(连接成功); //trans text data QByteArray ba QString(link success).toUtf8(); m_tcpSocket-write(ba); m_tcpSocket-flush(); //trans binary // struct{ // uint frameHead; // uint framdId; // uint dataLength; // }aFrame; // char buf[8192]; // memset(buf,0,8192); // aFrame.frameHead 1001; // aFrame.framdId 10; // aFrame.dataLength sizeof(int); // int dat 15; // memcpy(buf,aFrame,sizeof(aFrame)); // memcpy(bufsizeof(aFrame),dat,sizeof(int)); // m_tcpSocket-write(buf,8192); // m_tcpSocket-flush(); } void MainWindow::tcpDisconnected() { qDebug() QString(断开连接); }附录1 TCP传输模型原文链接Qt之TCP、UDP传输模型_qtcp发送端速度-CSDN博客附录2 UDP传输模型原文链接Qt之TCP、UDP传输模型_qtcp发送端速度-CSDN博客
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑