Socket通信
Qt中提供的所有的Socket类都是非阻塞的。
Qt中常用的用于socket通信的套接字类:
QTcpServer
用于TCP/IP通信, 作为服务器端套接字使用
QTcpSocket
用于TCP/IP通信,作为客户端套接字使用。
QUdpSocket
用于UDP通信,服务器,客户端均使用此套接字。
TCP/IP
在Qt中实现TCP/IP服务器端通信的流程:
创建套接字
将套接字设置为监听模式
等待并接受客户端请求
可以通过QTcpServer提供的void newConnection()信号来检测是否有连接请求,如果有可以在对应的槽函数中调用nextPendingConnection函数获取到客户端的Socket信息(返回值为QTcpSocket*类型指针),通过此套接字与客户端之间进行通信。
接收或者向客户端发送数据
接收数据:使用read()或者readAll()函数
发送数据:使用write()函数
客户端通信流程:
创建套接字
连接服务器
可以使用QTcpSocket类的connectToHost()函数来连接服务器。
向服务器发送或者接受数据
下面例子为简单的TCP/IP通信的实现:
Linux下的TCP通信:
Qt下的TCP通信:
服务器端
ui文件:
serverwidget.h文件
serverwidget.cpp文件
#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);
setWindowTitle("服务器:8888");
tcpServer->listen(QHostAddress::Any,8888); //监听本地所有网卡的地址
//当成功建立连接之后,触发槽函数
connect(tcpServer,&QTcpServer::newConnection, [=](){
//取出建立好链接的套接字
tcpSocket = tcpServer->nextPendingConnection();
//获取客户端的IP和端口地址
QString ip = tcpSocket->peerAddress().toString();
qint16 port = tcpSocket->peerPort();
QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);
ui->textEditRead->setText(temp);
//
connect(tcpSocket, &QTcpSocket::readyRead, [=](){
//从套接字中取出内容
QByteArray array = tcpSocket->readAll();
ui->textEditRead->append(array);
});
});
}
serverWidget::~serverWidget()
{
delete ui;
}
void serverWidget::on_buttonSend_clicked()
{
if(NULL == tcpSocket)
{
return ;
}
//先获取编辑区的内容
QString str = ui->textEditWrite->toPlainText();
tcpSocket->write(str.toUtf8().data());
}
void serverWidget::on_pushButton_2_clicked()
{
if(NULL == tcpSocket)
{
return ;
}
//主动和客户端断开连接
tcpSocket->disconnectFromHost();
tcpSocket->close();
tcpSocket = NULL;
}
客户端
UI文件:
clientwidget.h文件
clientwidget.cpp文件
#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QHostAddress>
ClientWidget::ClientWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ClientWidget)
{
ui->setupUi(this);
tcpSocket = NULL;
//分配空间,指定父对象
tcpSocket = new QTcpSocket(this);
setWindowTitle("客户端");
connect(tcpSocket, &QTcpSocket::connected, [=](){
ui->textEditRead->setText("成功和服务器建立连接");
});
connect(tcpSocket, &QTcpSocket::readyRead, [=](){
//获取对方发送的内容
QByteArray array = tcpSocket->readAll();
ui->textEditRead->append(array);
});
}
ClientWidget::~ClientWidget()
{
delete ui;
}
void ClientWidget::on_buttonConnect_clicked()
{
//获取服务器ip和端口
QString IP = ui->lineEditIp->text();
qint16 port = ui->lineEditPort->text().toInt();
//主动和服务器建立连接
tcpSocket->connectToHost(QHostAddress(IP),port);
}
void ClientWidget::on_buttonSend_clicked()
{
if(NULL == tcpSocket)
{
return ;
}
//获取编辑框内容
QString str = ui->textEditWrite->toPlainText();
//发送数据
tcpSocket->write(str.toUtf8().data());
}
void ClientWidget::on_pushButton_3_clicked()
{
//主动和对方断开连接
tcpSocket->disconnectFromHost();
tcpSocket->close();
}
main.cpp文件