网络编程有TCP和UDP。
TCP编程需要用到两个类:
1、QTcpServer——实现服务器的端口监听,可以提供一种服务。
2、QTcpSocket——实现套接字类,有消息的封装,可以读取和写入。
注意: QTcpServer、和QTcpSocket两个类在服务器中会用到,而客户端中只用到QTcpSocket类
一、服务器端
1、QT中TCP服务器的开发思路
1、开启服务器开启端口服务:建立QTcpServer对象,并用其中的listen()方法就可以开启指定的端口。
tcpServer->listen(QHostAddress::Any,ui->lineEdit_port->text().toUInt()); //服务器对端口号进行监听
2、当有客户端连接到服务器时,系统会接收到newConnection信号,所以需要在对应的槽函数中获取用于通信的套接字(QTcpServer的nextPendingConnection()函数获取套接字)。
tcpSocket = tcpServer->nextPendingConnection(); //获取与客户端进行通信的套接字
3、客户端有数据过来,则会产生一个readyRead信号,从对应的槽函数中通过套接字的readAll()等相关函数读取数据。
buf = QString(tcpSocket->readAll()); //用套接字读取客户端发来的数据
4、通过套接字的write()函数向客户端发送数据。
tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data());
2、QT服务器界面设计
3、QT服务器代码实现
(1)、添加模块和和头文件
1)在pro文件中添加一行内容:QT += network
2)在widget.h头文件中添加需要用到的服务器头文件
#include "QTcpServer"
#include "QTcpSocket"
(2)在widget构造函数中创建QTcpServer、和QTcpSocket对象
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
tcpServer = new QTcpServer(this); //创建一个服务器类
tcpSocket = new QTcpSocket(this); //创建一个socket类
}
(3)写”启动服务器"按键的槽函数(实现按下就启动服务器,再次按下就关闭服务器)
服务器实现监听;将newConnection信号和槽函数进行绑定
void Widget::on_pushButton_startOrStop_clicked()
{
if(ui->pushButton_startOrStop->text() == "启动服务器")
{
tcpServer->listen(QHostAddress::Any,ui->lineEdit_port->text().toUInt()); //服务器对端口号进行监听
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection_slot())); //有网络用户连接进来,就会执行槽函数
ui->pushButton_startOrStop->setText("关闭服务器");
ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/server_open.png);");
}
else
{
tcpServer->close();
ui->pushButton_startOrStop->setText("启动服务器");
ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/server_close.png);");
}
}
(4)有用户连接服务器时,系统收到newConnection信号,这里写对应的槽函数
进入这个槽函数表示有用户连接进来了,所以获取该套接字;并判断是否接收客户端数据(readyRead信号和槽函数绑定)
在头文件中声明槽函数
private slots:
void newConnection_slot();
实现槽函数功能
void Widget::newConnection_slot()
{
tcpSocket = tcpServer->nextPendingConnection(); //获取与客户端进行通信的套接字
ui->label_clientIp->setText(tcpSocket->peerAddress().toString()); //获取客户端的IP地址
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot())); //客户端有数据到达服务器,就会产生readyRead信号
}
(5)服务器接收到数据后,会产生readyRead信号,这里实现对应槽函数功能
在头文件中声明槽函数
private slots:
void readyRead_slot();
实现槽函数功能:接收来自客户端的数据
void Widget::readyRead_slot()
{
QString buf;
buf = QString(tcpSocket->readAll()); //用套接字读取客户端发来的数据
ui->plainTextEdit_receive->appendPlainText(buf);
}
(6)实现“发送”按钮的槽函数
void Widget::on_pushButton_send_clicked()
{
tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data());
}
二、客户端
1、QT中TCP客户端的开发思路
1、创建QTcpSocket对象,并用connectToHost()函数通过IP和端口号连接服务器。
tcpSocket = new QTcpSocket(this);
tcpSocket->connectToHost(ui->lineEdit_ip->text(),ui->lineEdit_port->text().toUInt()); //根据IP地址和端口号连接服务器
2、客户端成功连接上服务器,系统会产生connected信号。(所以需要将信号和槽函数进行绑定)
connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_slot())); //客户端连接服务器成功后会产生connected信号
3、客户端收到服务器发送来的数据,会产生readyRead信号,在connected信号对应的槽函数中,将readyRead信号和对应的槽函数进行绑定。
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot())); //和服务器连接成功后,就需要就收服务器发送过来的数据了,
4、通过套接字对象读取服务器发来的数据。(用readall()等函数)
tcpSocket->readAll(); //从套接字中读取服务器发来的数据
5、通过套接字向服务器发送数据。(用write()函数)
tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data()); //向服务器发送数据
2、QT客户端界面设计
3、QT客户端代码实现
(1)、添加模块和和头文件
1)在pro文件中添加一行内容:QT += network
2)在widget.h头文件中添加需要用到的服务器头文件
#include "QTcpSocket"
(2)在widget构造函数中创建QTcpSocket对象
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
tcpSocket = new QTcpSocket(this); //创建一个socket类
}
(3)实现“连接服务器”按钮的槽函数
void Widget::on_pushButton_startOrStop_clicked()
{
if(ui->pushButton_startOrStop->text() == "连接服务器") //表示可以连接服务器
{
tcpSocket->connectToHost(ui->lineEdit_ip->text(),ui->lineEdit_port->text().toUInt()); //根据IP地址和端口号连接服务器
connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_slot())); //客户端连接服务器成功后会产生connected信号
ui->pushButton_startOrStop->setText("断开连接"); //修改按键的提示字,为下次关闭做准备
ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/client_open.png);"); //修改标签的样式表
}
else //表示可以断开和服务器的连接
{
tcpSocket->close(); //断开和服务器的连接
ui->pushButton_startOrStop->setText("连接服务器"); //修改按键的提示字,为下次连接做准备
ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/client_close.png);");
}
}
(4)客户端连接到服务器会触发connected信号,实现对应槽函数
void Widget::connected_slot()
{
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot())); //和服务器连接成功后,就需要就收服务器发送过来的数据了,
//如果客户端收到发送过来的数据,系统会产生readyRead信号
}
(5)客户端收到服务器发送过来的数据会触发readyRead信号,实现对应槽函数
void Widget::readyRead_slot()
{
//这里是读取所有的信息,后期建议修改为分片读取,防止大文件一次读取不完
ui->plainTextEdit->appendPlainText(QString(tcpSocket->readAll())); //从套接字中读取服务器发来的数据
}
(6)为“发送”按钮实现槽函数
void Widget::on_pushButton_send_clicked()
{
//tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data()); //向服务器发送数据
tcpSocket->write(ui->lineEdit_send->text().toUtf8()); //可以接收到服务器发送过来的汉字
}
附工程源文件下载链接:
QT客户端+服务器源码下载