近期因为测试需要用到 TCPServer(TCP服务端)和 TCPClient(TCP客户端)来进行通信和数据的发送以及接受,所以用QT分别写了TCP服务端和TCP客户端,本文分享以下基于QT开发TCPServer和TCPClient的经验, 文中包括源码,在文末处包含项目的源码文件。
一、软件介绍
TCPServer可以绑定一个ip地址并监听一个端口,在TCPServer绑定并监听状态时,可以使用TCPClient来连接服务端绑定的ip地址和端口,连接成功后便可进行通信了。下面首先演示以下服务端和客户端界面以及通信流程。
1.1 TCPServer服务端界面
- 在服务端的界面中,“开始监听”按钮可以在设置“监听地址”、“监听端口”后点击既开始对此ip地址和端口进行监听,当有TCPClient客户端针对此ip地址和端口进行请求连接时便可进行连接,随后开始通信。
- “停止监听”可以停止对ip地址和端口号的监听。
- “清空文本框”按钮可以清空消息记录,方便连续信息的阅读。
- “退出”按钮即关闭此软件。
- “发送消息”可发送已经输入的内容。
1.2 TCPClient客户端界面
- 在客户端的界面中,“连接”按钮可以在设置“连接地址”、“端口”后点击既开始对此ip地址和端口进行请求连接,当有TCPServer服务端针对此ip地址和端口进行监听时便可进行连接,随后开始通信。
- “断开连接”可以讲服务端和客户端已经建立的连接断开。
- “清空文本框”按钮可以清空消息记录,方便连续信息的阅读。
- “发送消息”和“清除”按钮分别可发送和清除已经输入的内容。
- “退出”按钮即关闭此软件。
1.3 服务端和客户端建立连接并通信演示
- 首先在Server端我们绑定ip:192.168.31.222,端口:1200,然后点击“开始监听”按钮,这时服务端就开始等待Client端请求建立连接。
- 接下来我们使用客户端,连接地址和端口号设置为服务端所绑定的ip:192.168.31.222,端口:1200,然后点击“连接”按钮,可以看到双方建立连接成功,软件出现连接成功建立提示信息。
- 双方建立连接成功便可以开始通信,我们首先点击“清空文本框”把提示信息清除,然后使用TCPServer服务端发送一条信息“Hello,I’m TCPServer~”,可以看到客户端成功收到服务端发送的信息,[in]后边的内容为本端收到的信息,[out]后边的内容为本端发送的信息。
- 接下来我们使用TCPClient客户端给服务端发送一条信息“Hi,I’m TCPClient!”,可以看到服务端成功收到信息。
二、QT实现TCPServer和TCPClient
我们想要在QT中实现TCP通信需要在.pro文件中添加下面一行代码:
QT += network
2.1 TCPClient客户端
- 首先我们应该包含下面三个头文件来支持我们调用内部的通信函数:
#include <QTcpSocket>
#include <QHostAddress>
#include <QHostInfo>
- 创建QTcpSocket套接字对象
tcpClient = new QTcpSocket(this);
- 使用tcpClient 对象连接服务器
tcpClient ->connectToHost(IP, port);
- 然后我们用write()函数向服务器发送数据
tcpClient ->write(data);
- 当tcpClient 接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据
connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
void MainWindow::onSocketReadyRead()
{//readyRead()信号槽函数
while(tcpClient->canReadLine())
ui->plainTextEdit->appendPlainText("[in] "+tcpClient->readLine());
}
- 在我们通信完毕后需要断开连接
void MainWindow::on_actDisconnect_triggered()
{//断开与服务器的连接
if (tcpClient->state()==QAbstractSocket::ConnectedState)
tcpClient->disconnectFromHost();
}
下面给出TCPClient的代码
- main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QFile>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.resize(700,900);
w.show();
return a.exec();
}
- mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
#include <QLabel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QTcpSocket *tcpClient; //socket
QLabel *LabSocketState; //状态栏显示标签
QString getLocalIP();//获取本机IP地址
protected:
void closeEvent(QCloseEvent *event);
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
//自定义槽函数
void onConnected();
void onDisconnected();
void onSocketStateChange(QAbstractSocket::SocketState socketState);
void onSocketReadyRead();//读取socket传入的数据
void on_actConnect_triggered();
void on_actDisconnect_triggered();
void on_actClear_triggered();
void on_btnSend_clicked();
void on_btnClear_clicked();
void on_actionTimeCurrent_triggered();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
- mainwindow.cpp
#pragma execution_character_set("utf-8")
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
#include <QHostInfo>
#include <QDateTime>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
tcpClient = new QTcpSocket(this); //创建socket变量
LabSocketState = new QLabel("Socket状态:");//状态栏标签
LabSocketState->setMinimumWidth(250);
ui->statusBar->addWidget(LabSocketState);
QString localIP=getLocalIP();//本机IP
this->setWindowTitle("TCP客户端");
ui->comboServer->addItem(localIP);
setFocusPolicy(Qt::StrongFocus);
installEventFilter(this);
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()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onConnected()
{ //connected()信号槽函数
ui->plainTextEdit->appendPlainText("**已连接到服务器");
ui->plainTextEdit->appendPlainText("**peer address:"+tcpClient->peerAddress().toString());
ui->plainTextEdit->appendPlainText("**peer port:"+QString::number(tcpClient->peerPort()));
ui->actConnect->setEnabled(false);
ui->actDisconnect->setEnabled(true);
}
QString MainWindow::getLocalIP()
{
QString hostName = QHostInfo::localHostName();//本地主机名
QHostInfo hostInfo = QHostInfo::fromName(hostName);
QString localIP = "";
QList<QHostAddress> addList=hostInfo.addresses();
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;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (tcpClient->state() == QAbstractSocket::ConnectedState)
tcpClient->disconnectFromHost();
event->accept();
}
void MainWindow::onDisconnected()
{//disConnected()信号槽函数
ui->plainTextEdit->appendPlainText("**已断开与服务器的连接");
ui->actConnect->setEnabled(true);
ui->actDisconnect->setEnabled(false);
}
void MainWindow::onSocketReadyRead()
{//readyRead()信号槽函数
while(tcpClient->canReadLine())
ui->plainTextEdit->appendPlainText("[in] "+tcpClient->readLine());
}
void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{//stateChange()信号槽函数
switch(socketState)
{
case QAbstractSocket::UnconnectedState:
LabSocketState->setText("scoket状态:UnconnectedState");
break;
case QAbstractSocket::HostLookupState:
LabSocketState->setText("scoket状态:HostLookupState");
break;
case QAbstractSocket::ConnectingState:
LabSocketState->setText("scoket状态:ConnectingState");
break;
case QAbstractSocket::ConnectedState:
LabSocketState->setText("scoket状态:ConnectedState");
break;
case QAbstractSocket::BoundState:
LabSocketState->setText("scoket状态:BoundState");
break;
case QAbstractSocket::ClosingState:
LabSocketState->setText("scoket状态:ClosingState");
break;
case QAbstractSocket::ListeningState:
LabSocketState->setText("scoket状态:ListeningState");
}
}
void MainWindow::on_actConnect_triggered()
{//连接到服务器
QString addr=ui->comboServer->currentText();
quint16 port=ui->spinPort->value();
tcpClient->connectToHost(addr,port);
}
void MainWindow::on_actDisconnect_triggered()
{//断开与服务器的连接
if (tcpClient->state()==QAbstractSocket::ConnectedState)
tcpClient->disconnectFromHost();
}
void MainWindow::on_actClear_triggered()
{
ui->plainTextEdit->clear();
}
void MainWindow::on_btnSend_clicked()
{//发送数据
QString msg=ui->editMsg->toPlainText();
ui->plainTextEdit->appendPlainText("[out] "+msg);
ui->editMsg->setFocus();
QByteArray str = msg.toLatin1();
str.append("\r\n");
tcpClient->write(str);
}
void MainWindow::on_btnClear_clicked()
{
ui->editMsg->clear();
}
void MainWindow::on_actionTimeCurrent_triggered()
{
QString msg=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
ui->plainTextEdit->appendPlainText(+" [out] "+msg);
ui->editMsg->setFocus();
QByteArray str = msg.toLatin1();
str.append("\r\n\r\n");
tcpClient->write(str);
}
- ui界面
2.1 TCPServer服务端
- 首先需要包含下面的头文件来提供我们需要调用的函数:
#include <QTcpServer>
#include <QtNetwork>
- 然后创建TCPServer对象
tcpServer=new QTcpServer(this);
- 绑定ip并监听端口功能,为客户端可以通过这个端口访问服务器
tcpServer->listen(addr,port);
- 当tcpServer被tcpClient访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
void MainWindow::onNewConnection()
{
tcpSocket = tcpServer->nextPendingConnection(); //创建socket
connect(tcpSocket, SIGNAL(connected()),this, SLOT(onClientConnected()));
onClientConnected();
connect(tcpSocket, SIGNAL(disconnected()),this, SLOT(onClientDisconnected()));
connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
onSocketStateChange(tcpSocket->state());
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}
- 使用tcpSocket的write()函数向客户端发送数据
tcpSocket->write(data);
- 当tcpSocket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
void MainWindow::onSocketReadyRead()
{
while(tcpSocket->canReadLine()){
ui->plainTextEdit->appendPlainText("[in] "+tcpSocket->readLine());
}
}
- 停止监听
void MainWindow::on_actStop_triggered()
{
if (tcpServer->isListening()) //tcpServer正在监听
{
tcpServer->close();//停止监听
ui->actStart->setEnabled(true);
ui->actStop->setEnabled(false);
LabListen->setText("监听状态:已停止监听");
}
}
下面给出TCPServer的代码文章来源:https://www.toymoban.com/news/detail-611277.html
- main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.resize(600,700);
w.show();
return a.exec();
}
- mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QLabel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
protected:
void closeEvent(QCloseEvent *event);//关闭窗口时停止监听
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void onNewConnection();//QTcpServer的newConnection()信号
void onSocketStateChange(QAbstractSocket::SocketState socketState);//底部socket状态变化
void onClientConnected(); //客户端接入时
void onClientDisconnected();//客户端断开连接时
void onSocketReadyRead();//读取socket传入的数据
void on_actStart_triggered();//开始监听
void on_actStop_triggered();//停止监听
void on_actClear_triggered();//清空
void on_btnSend_clicked();//发送消息
void on_actHostInfo_triggered();//获取本机地址
private:
Ui::MainWindow *ui;
QLabel *LabListen;//状态栏标签
QLabel *LabSocketState;//状态栏标签
QTcpServer *tcpServer; //TCP服务器
QTcpSocket *tcpSocket;//TCP通讯的Socket
QString getLocalIP();//获取本机IP地址
};
#endif // MAINWINDOW_H
- mainwindow.cpp
#pragma execution_character_set("utf-8")
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
LabListen=new QLabel("监听状态:");
LabListen->setMinimumWidth(150);
ui->statusBar->addWidget(LabListen);
LabSocketState=new QLabel("Socket状态:");
LabSocketState->setMinimumWidth(200);
ui->statusBar->addWidget(LabSocketState);
QString localIP=getLocalIP();//本机IP
this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);
ui->comboIP->addItem(localIP);
tcpServer=new QTcpServer(this);
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}
MainWindow::~MainWindow()
{
delete ui;
}
QString MainWindow::getLocalIP()
{
QString hostName=QHostInfo::localHostName();//本地主机名
QHostInfo hostInfo=QHostInfo::fromName(hostName);
QString localIP="";
QList<QHostAddress> addList=hostInfo.addresses();
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;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (tcpServer->isListening())
tcpServer->close();//停止网络监听
event->accept();
}
void MainWindow::onNewConnection()
{
tcpSocket = tcpServer->nextPendingConnection(); //创建socket
connect(tcpSocket, SIGNAL(connected()),this, SLOT(onClientConnected()));
onClientConnected();
connect(tcpSocket, SIGNAL(disconnected()),this, SLOT(onClientDisconnected()));
connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
onSocketStateChange(tcpSocket->state());
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}
void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{
qDebug()<<"走到这了";
switch(socketState)
{
case QAbstractSocket::UnconnectedState:
LabSocketState->setText("scoket状态:UnconnectedState");
break;
case QAbstractSocket::HostLookupState:
LabSocketState->setText("scoket状态:HostLookupState");
break;
case QAbstractSocket::ConnectingState:
LabSocketState->setText("scoket状态:ConnectingState");
break;
case QAbstractSocket::ConnectedState:
LabSocketState->setText("scoket状态:ConnectedState");
break;
case QAbstractSocket::BoundState:
LabSocketState->setText("scoket状态:BoundState");
break;
case QAbstractSocket::ClosingState:
LabSocketState->setText("scoket状态:ClosingState");
break;
case QAbstractSocket::ListeningState:
LabSocketState->setText("scoket状态:ListeningState");
}
}
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();
// deleteLater();//QObject::deleteLater();
}
void MainWindow::onSocketReadyRead()
{
while(tcpSocket->canReadLine()){
ui->plainTextEdit->appendPlainText("[in] "+tcpSocket->readLine());
}
}
void MainWindow::on_actStart_triggered()
{
QString IP=ui->comboIP->currentText();//IP地址
quint16 port=ui->spinPort->value();//端口
QHostAddress addr(IP);
tcpServer->listen(addr,port);//
ui->plainTextEdit->appendPlainText("**开始监听...");
ui->plainTextEdit->appendPlainText("**服务器地址:"+tcpServer->serverAddress().toString());
ui->plainTextEdit->appendPlainText("**服务器端口:"+QString::number(tcpServer->serverPort()));
ui->actStart->setEnabled(false);
ui->actStop->setEnabled(true);
LabListen->setText("监听状态:正在监听");
}
void MainWindow::on_actStop_triggered()
{
if (tcpServer->isListening()) //tcpServer正在监听
{
tcpServer->close();//停止监听
ui->actStart->setEnabled(true);
ui->actStop->setEnabled(false);
LabListen->setText("监听状态:已停止监听");
}
}
void MainWindow::on_actClear_triggered()
{
ui->plainTextEdit->clear();
}
void MainWindow::on_btnSend_clicked()
{
QString msg=ui->editMsg->text();
ui->plainTextEdit->appendPlainText("[out] "+msg);
ui->editMsg->clear();
ui->editMsg->setFocus();
QByteArray str=msg.toUtf8();
str.append("\r\n");//添加一个换行符
tcpSocket->write(str);
}
void MainWindow::on_actHostInfo_triggered()
{
QString hostName=QHostInfo::localHostName();//本地主机名
ui->plainTextEdit->appendPlainText("本机主机名:"+hostName+"\n");
QHostInfo hostInfo=QHostInfo::fromName(hostName);
QList<QHostAddress> addList=hostInfo.addresses();//
if (!addList.isEmpty())
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
if (QAbstractSocket::IPv4Protocol==aHost.protocol())
{
QString IP=aHost.toString();
ui->plainTextEdit->appendPlainText("本机IP地址:"+aHost.toString());
if (ui->comboIP->findText(IP)<0)
ui->comboIP->addItem(IP);
}
}
}
- ui界面
三、代码分享
后续会写基于QT实现的UDP通信工具,下面给出代码。文章来源地址https://www.toymoban.com/news/detail-611277.html
- 百度网盘
TCPClient提取码1234
TCPServer提取码1234 - CSDN资源
TCPServer
TCPClient
到了这里,关于基于QT的TCP通信实现(TCPServer和TCPClient)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!