目录标题
- 一、开发基础知识
- 1、QT的网络编程: TCP和UDP
- 2、网络编程接口
-
- 二、TCP编程
-
- 三、UDP编程
- 四、源码
-
一、开发基础知识
1、QT的网络编程: TCP和UDP
TCP编程需要用到俩个类: QTcpServer 和 QTcpSocket
QTcpSocket类提供了一个TCP套接字
- QTcpSocket是QAbstractSocket的一个子类,它允许您建立TCP连接和传输数据流
注意:TCP套接字不能在QIODevice::Unbuffered模式下打开。
QTcpServer类提供一个基于tcp的服务器
2. 这个类可以接收传入的TCP连接。您可以指定端口或让QTcpServer自动选择一个端口。你可以监听一个特定的地址或所有机器的地址。
3. 调用listen()让服务器侦听传入的连接。然后,每当客户机连接到服务器时,都会发出newConnection()信号。
4. 调用nextPendingConnection()接受挂起的连接作为已连接的QTcpSocket。该函数返回一个指向QAbstractSocket::ConnectedState中的QTcpSocket的指针,您可以使用该指针
2、网络编程接口
1. listen
功能:设置监听数和分配端口,监听客户端连接
bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
如果address为QHostAddress::Any,服务器将侦听所有网络接口;
为QHostAddress::LocalHost,IPv4本地主机地址,相当于QHostAddress(“127.0.0.1”)
当“port”为“0”时,系统自动分配端口
成功 true;失败 false
2. connect
功能:connect,是QT中的连接函数,将信号发送者sender对象中的信号signal与接受者receiver中的member槽函数联系起来。当指定信号signal时必须使用宏SIGNAL () ,当指定槽函数时必须使用宏SLOT()
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context,
Func2 slot, Qt::ConnectionType type = Qt::AutoConnection)
二、TCP编程
目标创建一个TCP服务端和一个TCP 客户端简单网络调试助手
1、TCP服务端实现流程
1. 创建项目
创建一个Qt Widgets Application项目 | 项目名称和位置都不要包含中文 | 基类选择QWidget |
2. UI设计
接收窗口使用 QPlainTextEdit 并修改为只读
发送窗口使用 Line Edit
3. .h文件中包含头文件
#include <QTcpServer>
#include <QTcpSocket>
4. qmake文件中添加network
QT += core gui network
5. Widget类构造函数中创建QTcpServer和QTcpSocket的对象用作监听套接字
tcpServer = new QTcpServer(this);
tcpSocket = new QTcpSocket(this);
tcpServer 和 tcpSocket 对象指针需要在Widget类中声明
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
6. 使用listen()方法监听网卡的ip和端口(打开服务器)
侦听IPv4和IPv6接口,端口为portEdit输入的内容
void Widget::on_openBt_clicked()
{
tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt());
}
7. 如果有新的连接过来,并且连接成功,服务器会触发newConnection()信号,通过槽函数取出连接成功的socket
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection_Slot()));
void Widget::newConnection_Slot()
{
while (tcpServer->hasPendingConnections())
{
tcpSocket = tcpServer->nextPendingConnection();
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
}
}
8. 如果有数据成功传送过来,对方的通信套接字QTcpSocket会触发readyRead()信号,在槽函数可以进行读取
void Widget::readyRead_Slot()
{
QString buf = tcpSocket->readAll();
ui->recvEdit->appendPlainText(buf);
}
9. 发送数据
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}
10. 关闭套接字(关闭服务器)
void Widget::on_closeButton_clicked()
{
tcpSocket->close();
}
2、TCP客户端实现流程
1. 创建项目
基类选择QWidget
2. UI设计
3. .h文件中包含头文件
#include <QTcpServer>
#include <QTcpSocket>
4. qmake文件中添加network
QT += core gui network
5. Widget类构造函数中创建QTcpSocket的对象用作监听套接字
tcpSocket = new QTcpSocket(this);
tcpSocket 对象指针需要在Widget类中声明
QTcpSocket *tcpSocket;
6. connectTohost()绑定ip和端口号进行连接,连接成功会触发connected()信号,将该信号与槽函数关联
void Widget::on_openBt_clicked()
{
tcpSocket->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toUInt());
connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected_Slot()));
}
7. readyRead()信号和槽函数关联
void Widget::connected_Slot()
{
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
}
8. 读数据
void Widget::readyRead_Slot()
{
QString buf = tcpSocket->readAll();
ui->recvEdit->appendPlainText(buf);
}
9. 发送数据
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit());
}
10. 关闭套接字
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit());
}
三、UDP编程
udp通信这里不分服务端和客户端
1. 创建项目
基类选择QWidget
2. UI设计
3. .h文件中包含头文件
#include <QUdpSocket>
4. qmake文件中添加network
QT += core gui network
5. Widget类构造函数中创建QTcpSocket的对象用作监听套接字
udpSocket = new QUdpSocket(this);
udpsocket对象指针需要在Widget类中声明
QUdpSocket *udpSocket;
6. bind()设置本地端口号,准备读信号与槽函数关联(打开udp连接)
void Widget::on_openBt_clicked()
{
udpSocket->bind(ui->localPort->text().toUInt());
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_slot()));
}
7. 读数据
void Widget::readyRead_slot()
{
while(udpSocket->hasPendingDatagrams()) {
QByteArray array;
array.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(array.data(), array.size());
QString buf = array.data();
ui->recvEdit->appendPlainText(buf);
}
}
8. 发送数据
void Widget::on_sendBt_clicked()
{
QHostAddress address;
address.setAddress(ui->aimIp->text());
udpSocket->writeDatagram(ui->sendEdit->text().toLocal8Bit().data(),
ui->sendEdit->text().length(),
address,
ui->aimPort->text().toUInt());
}
- 关闭套接字
udpSocket->close();
四、源码
1. TCP服务端
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QString>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
private slots:
void newConnection_Slot();
void readyRead_Slot();
void on_openBt_clicked();
void on_closeButton_clicked();
void on_sendBt_clicked();
private:
Ui::Widget *ui;
};
#endif
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
tcpServer = new QTcpServer(this);
tcpSocket = new QTcpSocket(this);
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection_Slot()));
}
void Widget::newConnection_Slot()
{
while (tcpServer->hasPendingConnections())
{
tcpSocket = tcpServer->nextPendingConnection();
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
}
}
void Widget::readyRead_Slot()
{
QString buf = tcpSocket->readAll();
ui->recvEdit->appendPlainText(buf);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_openBt_clicked()
{
tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt());
}
void Widget::on_closeButton_clicked()
{
tcpSocket->close();
}
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}
2. TCP客户端
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QString>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
QTcpSocket *tcpSocket;
~Widget();
private slots:
void connected_Slot();
void readyRead_Slot();
void on_closeBt_clicked();
void on_sendBt_clicked();
void on_openBt_clicked();
private:
Ui::Widget *ui;
};
#endif
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
tcpSocket = new QTcpSocket(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::connected_Slot()
{
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
}
void Widget::readyRead_Slot()
{
QString buf = tcpSocket->readAll();
ui->recvEdit->appendPlainText(buf);
}
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit());
}
void Widget::on_closeBt_clicked()
{
tcpSocket->close();
}
void Widget::on_openBt_clicked()
{
tcpSocket->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toUInt());
connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected_Slot()));
}
3. UDP
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QUdpSocket>
#include <QString>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
QUdpSocket *udpSocket;
private slots:
void on_openBt_clicked();
void readyRead_slot();
void on_sendBt_clicked();
void on_closeBt_clicked();
private:
Ui::Widget *ui;
};
#endif
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
udpSocket = new QUdpSocket(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_openBt_clicked()
{
udpSocket->bind(ui->localPort->text().toUInt());
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_slot()));
}
void Widget::readyRead_slot()
{
while(udpSocket->hasPendingDatagrams()) {
QByteArray array;
array.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(array.data(), array.size());
QString buf = array.data();
ui->recvEdit->appendPlainText(buf);
}
}
void Widget::on_sendBt_clicked()
{
QHostAddress address;
address.setAddress(ui->aimIp->text());
udpSocket->writeDatagram(ui->sendEdit->text().toLocal8Bit().data(),
ui->sendEdit->text().length(),
address,
ui->aimPort->text().toUInt());
}
void Widget::on_closeBt_clicked()
{
udpSocket->close();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)