第一:网络编程基本简介
要想在程序中使用QT网络模块,需要在pro项目配置文件里增加下面的一条;
QT += network
第二:TCP通信简介
TCP 协议(Transmission Control Protocol)全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP 通信必须先建立 TCP 连接,通信端分为客户端和服务端。服务端通过监听某个端口来监听是否有客户端连接到来,如果有连接到来,则建立新的 socket 连接;客户端通过 ip 和port 连接服务端,当成功建立连接之后,就可进行数据的收发了。需要注意的是,在 Qt 中,Qt 把 socket 当成输入输出流来对待的,数据的收发是通过 read()和 write()来进行的,需要与我 们常见的send()与 recv()进行区分。
第三:TCP服务器端代码具体实现
本例大体流程首先获取本地 IP 地址。创建一个 tcpSocket 套接字,一个 tcpServer 服务端。点击监听即监听本地的主机 IP 地址和端口,同时等待服务端的连接。此程序需要结合客户端一起使用。
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 #include <QTcpServer> 6 #include <QTcpSocket> 7 #include <QVBoxLayout> 8 #include <QHBoxLayout> 9 #include <QPushButton> 10 #include <QTextBrowser> 11 #include <QLabel> 12 #include <QComboBox> 13 #include <QSpinBox> 14 #include <QHostInfo> 15 #include <QLineEdit> 16 #include <QNetworkInterface> 17 #include <QDebug> 18 19 class MainWindow : public QMainWindow 20 { 21 Q_OBJECT 22 23 public: 24 MainWindow(QWidget *parent = nullptr); 25 ~MainWindow(); 26 27 private: 28 /* tcp 服务器 */ 29 QTcpServer *tcpServer; 30 31 /* 通信套接字 */ 32 QTcpSocket *tcpSocket; 33 34 /* 按钮 */ 35 QPushButton *pushButton[4]; 36 37 /* 标签文本 */ 38 QLabel *label[2]; 39 40 /* 水平容器 */ 41 QWidget *hWidget[3]; 42 43 /* 水平布局 */ 44 QHBoxLayout *hBoxLayout[3]; 45 46 /* 垂直容器 */ 47 QWidget *vWidget; 48 49 /* 垂直布局 */ 50 QVBoxLayout *vBoxLayout; 51 52 /* 文本浏览框 */ 53 QTextBrowser *textBrowser; 54 55 /* 用于显示本地 ip */ 56 QComboBox *comboBox; 57 58 /* 用于选择端口 */ 59 QSpinBox *spinBox; 60 61 /* 文本输入框 */ 62 QLineEdit *lineEdit; 63 64 /* 存储本地的 ip 列表地址 */ 65 QList<QHostAddress> IPlist; 66 67 /* 获取本地的所有 ip */ 68 void getLocalHostIP(); 69 70 private slots: 71 /* 客户端连接处理槽函数 */ 72 void clientConnected(); 73 74 /* 开始监听槽函数 */ 75 void startListen(); 76 77 /* 停止监听槽函数 */ 78 void stopListen(); 79 80 /* 清除文本框时的内容 */ 81 void clearTextBrowser(); 82 83 /* 接收到消息 */ 84 void receiveMessages(); 85 86 /* 发送消息 */ 87 void sendMessages(); 88 89 /* 连接状态改变槽函数 */ 90 void socketStateChange(QAbstractSocket::SocketState); 91 }; 92 #endif // MAINWINDOW_H
第四:源文件mainwindow.cpp的具体实现
1 #include "mainwindow.h" 2 3 MainWindow::MainWindow(QWidget *parent) 4 : QMainWindow(parent) 5 { 6 /* 设置主窗体的位置与大小 */ 7 this->setGeometry(0, 0, 800, 480); 8 9 /* 实例化 tcp 服务器与 tcp 套接字 */ 10 tcpServer = new QTcpServer(this); 11 tcpSocket = new QTcpSocket(this); 12 13 /* 开始监听按钮 */ 14 pushButton[0] = new QPushButton(); 15 /* 停止监听按钮 */ 16 pushButton[1] = new QPushButton(); 17 /* 清空聊天文本按钮 */ 18 pushButton[2] = new QPushButton(); 19 /* 发送消息按钮 */ 20 pushButton[3] = new QPushButton(); 21 22 /* 水平布局一 */ 23 hBoxLayout[0] = new QHBoxLayout(); 24 /* 水平布局二 */ 25 hBoxLayout[1] = new QHBoxLayout(); 26 /* 水平布局三 */ 27 hBoxLayout[2] = new QHBoxLayout(); 28 /* 水平布局四 */ 29 hBoxLayout[3] = new QHBoxLayout(); 30 31 /* 水平容器一 */ 32 hWidget[0] = new QWidget(); 33 /* 水平容器二 */ 34 hWidget[1] = new QWidget(); 35 /* 水平容器三 */ 36 hWidget[2] = new QWidget(); 37 38 vWidget = new QWidget(); 39 vBoxLayout = new QVBoxLayout(); 40 41 /* 标签实例化 */ 42 label[0] = new QLabel(); 43 label[1] = new QLabel(); 44 45 lineEdit = new QLineEdit(); 46 comboBox = new QComboBox(); 47 spinBox = new QSpinBox(); 48 textBrowser = new QTextBrowser(); 49 50 label[0]->setText("监听 IP 地址:"); 51 label[1]->setText("监听端口:"); 52 53 /* 设置标签根据文本文字大小自适应大小 */ 54 label[0]->setSizePolicy(QSizePolicy::Fixed, 55 QSizePolicy::Fixed); 56 label[1]->setSizePolicy(QSizePolicy::Fixed, 57 QSizePolicy::Fixed); 58 59 /* 设置端口号的范围,注意不要与主机的已使用的端口号冲突 */ 60 spinBox->setRange(10000, 99999); 61 62 pushButton[0]->setText("开始监听"); 63 pushButton[1]->setText("停止监听"); 64 pushButton[2]->setText("清空文本"); 65 pushButton[3]->setText("发送消息"); 66 67 /* 设置停止监听状态不可用 */ 68 pushButton[1]->setEnabled(false); 69 70 /* 设置输入框默认的文本 */ 71 lineEdit->setText("www.openedv.com 正点原子论坛"); 72 73 /* 水平布局一添加内容 */ 74 hBoxLayout[0]->addWidget(pushButton[0]); 75 hBoxLayout[0]->addWidget(pushButton[1]); 76 hBoxLayout[0]->addWidget(pushButton[2]); 77 78 /* 设置水平容器一的布局为水平布局一 */ 79 hWidget[0]->setLayout(hBoxLayout[0]); 80 81 /* 水平布局二添加内容 */ 82 hBoxLayout[1]->addWidget(label[0]); 83 hBoxLayout[1]->addWidget(comboBox); 84 hBoxLayout[1]->addWidget(label[1]); 85 hBoxLayout[1]->addWidget(spinBox); 86 87 /* 设置水平容器二的布局为水平布局二 */ 88 hWidget[1]->setLayout(hBoxLayout[1]); 89 90 /* 水平布局三添加内容 */ 91 hBoxLayout[2]->addWidget(lineEdit); 92 hBoxLayout[2]->addWidget(pushButton[3]); 93 94 /* 设置水平容器三的布局为水平布局一 */ 95 hWidget[2]->setLayout(hBoxLayout[2]); 96 97 /* 垂直布局添加内容 */ 98 vBoxLayout->addWidget(textBrowser); 99 vBoxLayout->addWidget(hWidget[1]); 100 vBoxLayout->addWidget(hWidget[0]); 101 vBoxLayout->addWidget(hWidget[2]); 102 103 /* 设置垂直容器的布局为垂直布局 */ 104 vWidget->setLayout(vBoxLayout); 105 106 /* 居中显示 */ 107 setCentralWidget(vWidget); 108 109 /* 获取本地 ip */ 110 getLocalHostIP(); 111 112 /* 信号槽连接 */ 113 connect(pushButton[0], SIGNAL(clicked()), 114 this, SLOT(startListen())); 115 connect(pushButton[1], SIGNAL(clicked()), 116 this, SLOT(stopListen())); 117 connect(pushButton[2], SIGNAL(clicked()), 118 this, SLOT(clearTextBrowser())); 119 connect(pushButton[3], SIGNAL(clicked()), 120 this, SLOT(sendMessages())); 121 connect(tcpServer, SIGNAL(newConnection()), 122 this, SLOT(clientConnected())); 123 } 124 125 MainWindow::~MainWindow() 126 { 127 }
总结:QT中有丰富的C++接口函数,利用好这些接口函数可以实现各种各样的功能,各位开发者可以根据自己的实际需求进行学习。