QT示例:基于TCP点对点通讯
- 一、 概述
- 二、TCP 协议工作原理
- 三、TCP 编程模型
- 四、基于TCP点对点通讯示例
- 1、客户端
- 2、客户端Client示例
- 3、服务器
- 4、服务器server示例
下载:基于TCP点对点通讯
一、 概述
二、TCP 协议工作原理
三、TCP 编程模型
四、基于TCP点对点通讯示例
1、客户端
客户端的代码比服务器稍简单,总的来说,使用QT中的QTcpSocket类与服务器进行通信只需要以下5步:
1)创建QTcpSocket套接字对象
socket = new QTcpSocket();
2)使用这个对象连接服务器
socket->connectToHost(IP, port);
3)使用write函数向服务器发送数据
socket->write(data);
4)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据
QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);void myWidget::socket_Read_Data()
{QByteArray buffer;//读取缓冲区数据buffer = socket->readAll();
}
5)断开与服务器的连接(关于close()和disconnectFromHost()的区别,可以按F1看帮助)
socket->disconnectFromHost();
socket->close();
2、客户端Client示例
.pro文件添加:
QT +=network
myWidget.h 添加:
//#include <QtNetwork>
#include <QTcpSocket>
#include <QMessageBox>namespace Ui {
class myWidget;
}class myWidget : public QWidget
{Q_OBJECTpublic:explicit myWidget(QWidget *parent = 0);~myWidget();private slots:void on_pushButton_connect_clicked(); // 连接按钮void socket_Read_Data(); // 数据流读取void on_pushButton_send_clicked(); // 发送数据void socket_Disconnected(); // 连接中断
private:Ui::myWidget *ui;QTcpSocket *socket;QPalette Pal0,Pal1; // 调色板
};
myWidget.cpp 添加:
#include "mywidget.h"
#include "ui_mywidget.h"myWidget::myWidget(QWidget *parent):QWidget(parent),ui(new Ui::myWidget)
{ui->setupUi(this);// 一、创建QTcpSocket套接字对象socket = new QTcpSocket;ui->pushButton_send->setEnabled(false);ui->lineEdit_IP->setText("192.168.1.100");ui->lineEdit_port->setText("8010");Pal0 =ui->pushButton_connect->palette();Pal1.setColor(QPalette::ButtonText,Qt::red); // 只能对按钮文本、窗口文本的动态颜色设置//连接信号槽QObject::connect(socket, &QTcpSocket::readyRead, this, &myWidget::socket_Read_Data);QObject::connect(socket, &QTcpSocket::disconnected, this, &myWidget::socket_Disconnected);
}myWidget::~myWidget()
{delete this->socket;delete ui;
}// 二、连接服务器
void myWidget::on_pushButton_connect_clicked()
{if(ui->pushButton_connect->text() == tr("连接")){//获取IP地址QString IP = ui->lineEdit_IP->text();//获取端口号int port = ui->lineEdit_port->text().toInt();//取消已有的连接socket->abort();//连接服务器(使用socket对象连接服务器)socket->connectToHost(IP, port);//等待连接成功if(!socket->waitForConnected(30000)){QMessageBox::information(this,tr("提示"),tr("Connection failed!"),QMessageBox::Ok);return;}QMessageBox::information(this,tr("提示"),tr("Connect successfully!"),QMessageBox::Ok);// 更新界面ui->pushButton_send->setEnabled(true);ui->pushButton_connect->setText("断开连接");ui->pushButton_connect->setPalette(Pal1);}else{//断开连接socket->disconnectFromHost();socket->close();// 更新界面ui->pushButton_send->setEnabled(false);ui->pushButton_connect->setText("连接");ui->pushButton_connect->setPalette(Pal0);}
}// 三、接受/读取数据:使用socket的write函数向客户端发送数据
void myWidget::socket_Read_Data()
{// 读取缓冲区数据QByteArray buffer= socket->readAll();if(!buffer.isEmpty()){QString str =ui->textEdit_receive->toPlainText();str += buffer+"\n";// 刷新显示接受到的数据ui->textEdit_receive->setText(str);}
}// 四、发送按钮:使用socket的write函数向客户端发送数据
void myWidget::on_pushButton_send_clicked()
{//获取文本框内容并以ASCII码形式发送socket->write(ui->textEdit_send->toPlainText().toLatin1());socket->flush(); // 冲掉 缓存
}// 五、断开连接
void myWidget::socket_Disconnected()
{ui->pushButton_send->setEnabled(false);QMessageBox::information(this, tr("提示"),tr("Disconnected!"), QMessageBox::Ok);
}
界面:
3、服务器
二、服务器
服务器使用到了QTcpSocket类和QTcpSever类。用到了6个步骤:
1)创建QTcpSever对象
server = new QTcpServer();
2)侦听一个端口,使得客户端可以使用这个端口访问服务器
server->listen(QHostAddress::Any, port)
3)当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问
connect(server,&QTcpServer::newConnection,this,&mywidget::server_New_Connect);void MainWindow::server_New_Connect()
{//获取客户端连接(获得连接过来的客户端信息)socket = server->nextPendingConnection();
}
4)使用socket的write函数向客户端发送数据
socket->write(data);
5)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据
QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);void MainWindow::socket_Read_Data()
{QByteArray buffer;//读取缓冲区数据buffer = socket->readAll();
}
6)取消侦听
server->close();
4、服务器server示例
.pro文件添加:
QT +=network
myWidget.h 添加:
//#include <QtNetwork>
#include <QTcpServer>
#include <QTcpSocket>
#include <QMessageBox>namespace Ui {
class myWidget;
}class myWidget : public QWidget
{Q_OBJECTpublic:explicit myWidget(QWidget *parent = 0);~myWidget();private slots:void server_New_Connect();void socket_Read_Data();void socket_Disconnected();void on_pushButton_listen_clicked();void on_pushButton_send_clicked();private:Ui::myWidget *ui;
private:QTcpServer *server;QTcpSocket *socket;QPalette Pal0,Pal1; // 调色板bool socket_IsConnected =false ;};
myWidget.cpp 添加:
#include "mywidget.h"
#include "ui_mywidget.h"myWidget::myWidget(QWidget *parent):QWidget(parent),ui(new Ui::myWidget)
{ui->setupUi(this);ui->lineEdit_port->setText("8010");ui->lineEdit_ip->setText(QNetworkInterface().allAddresses().at(1).toString()); //获取本地IPui->lineEdit_ip->setEnabled(false); // 只能用主机IP 作为服务端ui->pushButton_send->setEnabled(false);Pal0=ui->pushButton_listen->palette();Pal1.setColor(QPalette::ButtonText,Qt::red); // 此方式 只能对按钮文本、窗口文本的动态颜色设置// 一 、创建QTcpSever对象;server = new QTcpServer();//连接信号槽(服务端被访问时,自动触发newconnection 信号,绑定槽函数 server new connect)connect(server,&QTcpServer::newConnection,this,&myWidget::server_New_Connect);}myWidget::~myWidget()
{server->close();server->deleteLater();delete ui;
}// 二、监听按钮:监听端口
void myWidget::on_pushButton_listen_clicked()
{if(ui->pushButton_listen->text()==tr("开始监听")){// 1.获取端口号QHostAddress IP(ui->lineEdit_ip->text()); // 服务器IPint port = ui->lineEdit_port->text().toInt();// 2.监听指定的端口(主机地址)if(!server->listen(IP,port)){// 若出错,则输出错误信息QMessageBox::warning(this, tr("错误"),tr("监听失败!"), QMessageBox::Ok);return;}ui->pushButton_listen->setText("取消监听"); // 修改键文字ui->pushButton_listen->setPalette(Pal1);// ui->pushButton_listen->setStyleSheet("background-color:rgb(255,255,0)"); // 改变按钮背景颜色}else{//if(socket->state() == QAbstractSocket::ConnectedState) // 若socket没有指定对象会有异常if(socket_IsConnected){//关闭连接socket->disconnectFromHost();socket_IsConnected =false;}// 4.关闭服务端server->close();QMessageBox::information(this, tr("提示"),tr("已取消监听"), QMessageBox::Ok);// 更新界面ui->pushButton_listen->setText("开始监听");ui->pushButton_listen->setPalette(Pal0);ui->pushButton_send->setEnabled(false);}
}// 三、建立新连接(当服务器接收到客户端信号时)
void myWidget::server_New_Connect()
{//获取客户端连接(获得连接过来的客户端信息)socket = server->nextPendingConnection();//连接QTcpSocket的信号槽,以读取新数据(服务器接收到客户端数据后,自动触发 readyRead 信号)QObject::connect(socket, &QTcpSocket::readyRead, this, &myWidget::socket_Read_Data);// 关闭连接(客户端断开连接后,自动触发 disconnect 信号)QObject::connect(socket, &QTcpSocket::disconnected, this, &myWidget::socket_Disconnected);ui->pushButton_send->setEnabled(true);QMessageBox::information(this,tr("提示"),tr("A Client connect!"),QMessageBox::Ok);socket_IsConnected= true;
}
// 四、接受/读取数据:使用socket的write函数向客户端发送数据
void myWidget::socket_Read_Data()
{// 读取缓冲区数据QByteArray buffer= socket->readAll();if(!buffer.isEmpty()){QString str =ui->textEdit_receive->toPlainText();str +=buffer+"\n";// 刷新显示接受到的数据ui->textEdit_receive->setText(str);}
}// 五、发送按钮:使用socket的write函数向客户端发送数据
void myWidget::on_pushButton_send_clicked()
{//获取文本框内容并以ASCII码形式发送(Latin1 编码规范)socket->write(ui->textEdit_send->toPlainText().toLatin1());socket->flush();
}// 六、断开连接
void myWidget::socket_Disconnected()
{ui->pushButton_send->setEnabled(false);QMessageBox::information(this, tr("提示"),tr("Disconnected!"), QMessageBox::Ok);
}
界面: