TCP通信包括两个部分 具体原理可以去百度一下,此处之展现实现过程,不过代码确实又臭又长,可以参考,请谨慎使用。关键部分代码解释在下面代码块中加了注释。
TCP通信包括一个是客户端 ,一个是服务端,接下来份两部分简单讲解一下QT如何实现两部分的通信的
服务端实现过程
VS下QT需要引入network模块
需要如下头文件
#include<QTcpSocket>
#include<QTcpServer>
这两个头文件与建立连接和传输数据有关。
服务端的.h文件
#pragma once
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")// 该指令仅支持VS环境
#endif
#include <QtWidgets/QWidget>
#include "ui_Sever.h"
#include<QTcpSocket>
#include<QTcpServer>
class Sever : public QWidget
{
Q_OBJECT
public:
Sever(QWidget *parent = nullptr);
~Sever();
public slots:
void on_listenBtn_clicked();
void on_SendBtn_clicked();
void New_Connect();
void Read_Data();
void Socket_Disconnected();
private:
Ui::SeverClass ui;
QTcpServer* m_server;
QTcpSocket* m_socket;
};
服务端的.cpp文件
#include "Sever.h"
Sever::Sever(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
ui.lineEditPort->setText("8000"); //端口号
ui.SendBtn->setEnabled(false); //设置按键使能
ui.lineEditPort->setReadOnly(false);
m_server = new QTcpServer(this); //new出QTCPSever指针对象
connect(m_server, &QTcpServer::newConnection, this, &Sever::New_Connect); // 侦听之后每次客户端对服务端进行连接时都会触发newConnection信号
}
Sever::~Sever()
{
}
void Sever::on_listenBtn_clicked()
{
qDebug() << "listenBtn()" << endl;
if (ui.listenBtn->text() == "侦听")
{
int port = ui.lineEditPort->text().toInt();
if (!m_server->listen(QHostAddress::Any, port)) //侦听判断
{
qDebug() << "Listen Failed" << m_server->errorString() << endl;
return;
}
qDebug() << "Listen Successed" << endl;
ui.listenBtn->setText("取消侦听");
ui.lineEditPort->setReadOnly(true);
}
else if (ui.listenBtn->text() == "取消侦听") //取消侦听
{
//m_socket->abort();
m_server->close();
ui.listenBtn->setText("侦听");
ui.SendBtn->setEnabled(false);
ui.lineEditPort->setReadOnly(false);
}
}
void Sever::on_SendBtn_clicked() //发送内容(此处可根据自己需求修改)
{
qDebug() << "SendBtn()" << endl;
QString str;
str = ui.textEdit->toPlainText();
m_socket->write(str.toUtf8());
m_socket->flush();
}
void Sever::New_Connect() //读取socket 链接
{
m_socket = m_server->nextPendingConnection(); //nextPendingConnection()返回挂起的socket
connect(m_socket, &QTcpSocket::readyRead, this, &Sever::Read_Data); //读取数据并解析
connect(m_socket, &QTcpSocket::disconnected, this, &Sever::Socket_Disconnected);
ui.SendBtn->setEnabled(true);
ui.lineEditPort->setReadOnly(true);
}
void Sever::Read_Data()
{
QByteArray buffer;
buffer = m_socket->readAll();
if (!buffer.isEmpty())
{
QString str = ui.textEdit_2->toPlainText();
str += buffer;
qDebug() << str << endl;
ui.textEdit_2->setText(str);
}
}
void Sever::Socket_Disconnected()
{
ui.SendBtn->setEnabled(false);
qDebug() << "disconnected successed" << endl;
ui.lineEditPort->setReadOnly(false);
}
客户端实现过程
客户端.h文件
#pragma once
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include <QtWidgets/QWidget>
#include "ui_Client1.h"
#include<QDebug>
#include<QTcpSocket>
class Client1 : public QWidget
{
Q_OBJECT
public:
Client1(QWidget *parent = nullptr);
~Client1();
public slots:
void on_ConnectBtn_clicked();
void on_SendBtn_clicked();
void Socket_Read_Data();
void Socket_Disconnect();
private:
Ui::Client1Class ui;
QTcpSocket* m_socket;
};
客户端.cpp文件
#include "Client1.h"
Client1::Client1(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_socket = new QTcpSocket(this);
ui.lineEdit_IP->setText("192.168.137.50"); //链接服务端IP
ui.lineEdit_Port->setText("8000"); // 端口号
ui.SendBtn->setEnabled(false);
connect(m_socket, &QTcpSocket::readyRead, this, &Client1::Socket_Read_Data);
connect(m_socket, &QTcpSocket::disconnected, this, &Client1::Socket_Disconnect);
ui.lineEdit_IP->setReadOnly(false);
ui.lineEdit_Port->setReadOnly(false);
}
Client1::~Client1()
{}
void Client1::on_ConnectBtn_clicked()
{
qDebug() << "ConnectBtn_clicked()" << endl;
if (ui.ConnectBtn->text() == "连接")
{
QString IP;
int Port;
IP = ui.lineEdit_IP->text();
Port = ui.lineEdit_Port->text().toInt();
m_socket->abort();
m_socket->connectToHost(IP, Port);
if (!m_socket->waitForConnected(30000)) //链接等待时间
{
qDebug() << m_socket->errorString() << endl; //报错链接失败原因
qDebug() << "Connect Failed!" << endl;
return;
}
qDebug() << "Connect Successed" << endl;
ui.ConnectBtn->setText("断开连接");
ui.SendBtn->setEnabled(true);
ui.lineEdit_IP->setReadOnly(true);
ui.lineEdit_Port->setReadOnly(true);
}
else if (ui.ConnectBtn->text() == "断开连接")
{
m_socket->disconnectFromHost();
ui.ConnectBtn->setText("连接");
ui.SendBtn->setEnabled(false);
ui.lineEdit_IP->setReadOnly(false);
ui.lineEdit_Port->setReadOnly(false);
}
}
void Client1::on_SendBtn_clicked()
{
qDebug() << "SendBtn_clicked()" << endl;
QString SendData = ui.textEdit->toPlainText();
m_socket->write(SendData.toUtf8());
qDebug() << SendData << endl;
/*m_socket->flush();*/
}
void Client1::Socket_Read_Data()
{
qDebug() << "Socket_read_data" << endl;
QByteArray buffer;
buffer = m_socket->readAll();
if (!buffer.isEmpty())
{
QString str = ui.textEdit_2->toPlainText();
str += buffer;
ui.textEdit_2->setText(str);
}
}
void Client1::Socket_Disconnect()
{
qDebug() << "Socket_Disconnect()" << endl;
ui.SendBtn->setEnabled(false);
ui.lineEdit_IP->setReadOnly(false);
ui.lineEdit_Port->setReadOnly(false);
ui.ConnectBtn->setText("连接");
}
效果大致就是这样。