先说一下自己对QT的TCP通信的简单理解
客户端Client
需要一个QTcpSocket
对象
常用函数有:
void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)
void disconnectFromHost()
QHostAddress peerAddress() const
QString peerName() const
qint16 peerPort() const
qint64 write(const char *data)
qint64 read(char *data, qint64 maxSize)
常用信号:
void readyRead()
void connected()
void disconnected()
QTcpSocket
就是一个可以和对方互动的一个对象
服务端Server
需要一个QTcpSocket
对象和一个QTcpServer
对象
QTcpSocket
用法跟上面一样
QTcpServer
常用函数:
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
QTcpSocket * nextPendingConnection()
常用信号:
void newConnection()
QTcpServer
的作用就是声明服务端,用于接收QTcpSocket
的连接信号
TCP大致通信流程:
Server监听目标地址并设置端口
若有Client在目标地址内并发送连接信号给Server,则Server与Client连接成功,两者通过Socket来通信
两者之间的Socket是对等关系,通过write发送消息,通过read接收消息
两者其中之一主动断开连接,Server继续监听
使用网络编程需要在pro文件中加入 QT += network
学到的新东西:
QString转char*:str.toUtf8().data()
TextEdit追加输出:ui->textEdit->append()
获取TextEdit内容:ui->textEdit->toPlainText()
客户端主要代码:
#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QHostAddress>
ClientWidget::ClientWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ClientWidget)
{
ui->setupUi(this);
TcpSocket = NULL;
setWindowTitle("客户端");
TcpSocket = new QTcpSocket(this);
connect(TcpSocket, &QTcpSocket::connected, //接收到连接信号
[=]()
{
QString str = QString("连接成功!\n[%1:%2]").
arg(TcpSocket->peerAddress().toString()). //获取对方IP
arg(TcpSocket->peerPort()); //获取对方端口
ui->textEditRead->setText(str);
}
);
connect(TcpSocket, &QTcpSocket::readyRead, //接收到消息信号
[=]()
{
QString str = "Serve:" + QString(TcpSocket->readAll());
ui->textEditRead->append(str);
}
);
}
ClientWidget::~ClientWidget()
{
delete ui;
}
void ClientWidget::on_pushButtonConnect_clicked()
{
QString IP = ui->lineEditIP->text();
qint16 port = ui->lineEditPort->text().toInt();
TcpSocket->connectToHost(QHostAddress(IP), port); //连接主机
}
void ClientWidget::on_pushButtonSend_clicked()
{
if(TcpSocket == NULL)
return;
QString str = ui->textEditWrite->toPlainText();
TcpSocket->write(str.toUtf8().data()); //发送消息
ui->textEditRead->append("Client:" + str);
ui->textEditWrite->clear();
}
void ClientWidget::on_pushButtonDisconnect_clicked()
{
if(TcpSocket == NULL)
return;
TcpSocket->disconnectFromHost(); //断开连接
TcpSocket->close(); //关闭Socket
ui->textEditRead->append("已断开连接!");
}
服务端主要代码:
#include "serverwidget.h"
#include "ui_serverwidget.h"
ServerWidget::ServerWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ServerWidget)
{
ui->setupUi(this);
TcpServer = NULL;
TcpSocket = NULL;
TcpServer = new QTcpServer(this);
TcpServer->listen(QHostAddress::Any, 8888); //设置监听IP地址和端口
setWindowTitle("服务器IP:127.0.0.1 服务器端口:8888");
connect(TcpServer, &QTcpServer::newConnection, //接收到连接信号
[=]()
{
TcpSocket = TcpServer->nextPendingConnection(); //连接等待的下一个客户端
QString str = QString("[%1:%2] 已成功连接").
arg(TcpSocket->peerAddress().toString()). //获取对方IP地址
arg(TcpSocket->peerPort()); //获取对方端口
ui->textEditRead->setText(str);
connect(TcpSocket, &QTcpSocket::readyRead, //接收到消息信号
[=]()
{
QString str = "Client:" + QString(TcpSocket->readAll());
ui->textEditRead->append(str);
}
);
}
);
}
ServerWidget::~ServerWidget()
{
delete ui;
}
void ServerWidget::on_pushButtonSend_clicked()
{
if(TcpSocket == NULL)
return;
QString str = ui->textEditWrite->toPlainText();
TcpSocket->write(str.toUtf8().data()); //发送消息
ui->textEditRead->append("Server:" + str);
ui->textEditWrite->clear();
}
void ServerWidget::on_pushButtonDisconnect_clicked()
{
if(TcpSocket == NULL)
return;
TcpSocket->disconnectFromHost(); //断开连接
TcpSocket->close(); //关闭Socket
TcpSocket = NULL;
}
在main.cpp中创建客户端/服务端的窗口对象 w2
用w2.show()同时运行2个窗口
效果图: