Qt的Socket通信

文章目录

  • Qt的Socket通信
  • 1 TCP/IP
  • 2. UDP
  • 3. TCP/IP 和 UDP的区别

Qt中提供的所有的Socket类都是非阻塞的。
Qt中常用的用于socket通信的套接字类:

  • QTcpServer

用于TCP/IP通信, 作为服务器端套接字使用

  • QTcpSocket

用于TCP/IP通信,作为客户端套接字使用。

  • QUdpSocket

用于UDP通信,服务器,客户端均使用此套接字。

1 TCP/IP

在Qt中实现TCP/IP服务器端通信的流程:

  • 创建套接字
  • 将套接字设置为监听模式
  • 等待并接受客户端请求
    可以通过QTcpServer提供的void newConnection()信号来检测是否有连接请求,如果有可以在对应的槽函数中调用nextPendingConnection函数获取到客户端的Socket信息(返回值为QTcpSocket*类型指针),通过此套接字与客户端之间进行通信
  • 接收或者向客户端发送数据
  • 接收数据:使用read()或者readAll()函数
  • 发送数据:使用write()函数

客户端通信流程:

  • 创建套接字
  • 连接服务器
  • 可以使用QTcpSocket类的connectToHost()函数来连接服务器。
  • 向服务器发送或者接受数据

下面例子为简单的TCP/IP通信的实现:
服务器端
通过Qt提供的QTcpServer类实现服务器端的socket通信:

//---------- tcpserver.h ------------
class TCPServer : public QMainWindow
{Q_OBJECTpublic:explicit TCPServer(QWidget *parent = 0);~TCPServer();public slots:void slotNewConnection();void slotReadyRead();private:Ui::TCPServer *ui;// 负责监听的套接字QTcpServer* m_server;// 负责通信的套接字QTcpSocket* m_client;
};//---------- tcpserver.cpp ------------
TCPServer::TCPServer(QWidget *parent) :QMainWindow(parent),ui(new Ui::TCPServer),m_server(NULL),m_client(NULL)
{ui->setupUi(this);//创建套接字对象m_server = new QTcpServer(this);//将套接字设置为监听模式m_server->listen(QHostAddress::Any, 9999);//通过信号接收客户端请求,如果收到链接请求会有newConnection信号connect(m_server, &QTcpServer::newConnection,
this, &TCPServer::slotNewConnection);
}TCPServer::~TCPServer()
{delete ui;
}void TCPServer::slotNewConnection()
{if(m_client == NULL){//处理客户端的连接请求,获取通信socketm_client = m_server->nextPendingConnection();//发送数据m_client->write("服务器连接成功!!!");//连接信号, 接收客户端数据,有数据到来会收到readyRead信号connect(m_client, &QTcpSocket::readyRead, this, &TCPServer::slotReadyRead);}
}void TCPServer::slotReadyRead()
{//接收数据QByteArray array = m_client->readAll();QMessageBox::information(this, "Client Message", array);
}

客户端
客户端通过使用Qt提供的QTcpSocket类可以方便的实现与服务器端的通信。

//------------- tcpclient.h ------------
class TCPClient : public QMainWindow
{Q_OBJECTpublic:explicit TCPClient(QWidget *parent = 0);~TCPClient();public slots:void slotReadyRead();void slotSendMsg();private:Ui::TCPClient *ui;QTcpSocket* m_client;};//------------- tcpclient.cpp --------------
TCPClient::TCPClient(QWidget *parent) :QMainWindow(parent),ui(new Ui::TCPClient)
{ui->setupUi(this);//创建套接字m_client = new QTcpSocket(this);//连接服务器m_client->connectToHost(QHostAddress("127.0.0.1"), 9999);//通过信号readyRead接收服务器数据connect(m_client, &QTcpSocket::readyRead,
this, &TCPClient::slotReadyRead);//发送按钮connect(ui->btnSend, &QPushButton::clicked,
this, &TCPClient::slotSendMsg);
}TCPClient::~TCPClient()
{delete ui;
}void TCPClient::slotReadyRead()
{//接收数据QByteArray array = m_client->readAll();QMessageBox::information(this, "Server Message", array);
}void TCPClient::slotSendMsg()
{QString text = ui->textEdit->toPlainText();//发送数据m_client->write(text.toUtf8());ui->textEdit->clear();
}

2. UDP

使用Qt提供的QUdpSocket进行UDP通信。在UDP方式下,客户端并不与服务器建立连接,它只负责调用发送函数向服务器发送数据。类似的服务器也不从客户端接收连接,只负责调用接收函数,等待来自客户端的数据的到达。

在UDP通信中,服务器端和客户端的概念已经显得有些淡化,两部分做的工作都大致相同:

  • 创建套接字
  • 绑定套接字
    在UDP中如果需要接收数据则需要对套接字进行绑定,只发送数据则不需要对套接字进行绑定。
  • 通过调用bind()函数将套接字绑定到指定端口上。
  • 接收或者发送数据
  • 接收数据:使用readDatagram()接收数据,函数声明如下:
qint64   readDatagram(char * data, qint64 maxSize,
QHostAddress * address = 0, quint16 * port = 0)参数:
data: 接收数据的缓存地址
maxSize: 缓存接收的最大字节数
address: 数据发送方的地址(一般使用提供的默认值)
port: 数据发送方的端口号(一般使用提供的默认值)
使用pendingDatagramSize()可以获取到将要接收的数据的大小,
根据该函数返回值来准备对应大小的内存空间存放将要接收的数据。
  • 发送数据: 使用writeDatagram()函数发送数据,函数声明如下:
qint64   writeDatagram(const QByteArray & datagram,
const QHostAddress & host, quint16 port)参数:
datagram:要发送的字符串
host:数据接收方的地址
port:数据接收方的端口号
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);udpsocket = new QUdpSocket(this);udpsocket->bind(9090);setWindowTitle("server port is 9090");connect(udpsocket,&QUdpSocket::readyRead,[=](){char buf[1024] = {0};QHostAddress clientaddr;quint16 clientport;quint64 size = udpsocket->readDatagram(buf,sizeof(buf),&clientaddr,&clientport);if(size> 0){QString str = QString("[%1 : %2] : %3").arg(clientaddr.toString()).arg(clientport).arg(buf);ui->textEdit->append(str);}});
}Widget::~Widget()
{delete ui;
}void Widget::on_ButtonSend_clicked()
{QString ip = ui->lineEditIP->text();quint16 port = ui->lineEditPort->text().toInt();QString str = ui->textEdit->toPlainText();udpsocket->writeDatagram(str.toUtf8(),QHostAddress(ip),port);
}

广播

  • 在使用QUdpSocket类的writeDatagram()函数发送数据的时候,其中第二个参数host应该指定为广播地址:QHostAddress::Broadcast此设置相当于QHostAddress(“255.255.255.255”)
  • 使用UDP广播的的特点:
  • 使用UDP进行广播,局域网内的其他的UDP用户全部可以收到广播的消息
  • UDP广播只能在局域网范围内使用

组播

  • 我们再使用广播发送消息的时候会发送给所有用户,但是有些用户是不想接受消息的,这时候我们就应该使用组播,接收方只有先注册到组播地址中才能收到组播消息,否则则接受不到消息。另外组播是可以在Internet中使用的。

在使用QUdpSocket类的writeDatagram()函数发送数据的时候,其中第二个参数host应该指定为组播地址,关于组播地址的分类:

  • 224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
  • 224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
  • 224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
  • 239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
    注册加入到组播地址需要使用QUdpSocket类的成员函数:
bool joinMulticastGroup(const QHostAddress & groupAddress)

3. TCP/IP 和 UDP的区别

Qt的Socket通信相关推荐

  1. qt中socket通信流程图_基于Qt的局域网通信设计说明书.doc

    文档控制记录 序号版本日期修改内容修改人审批人1V1.02017-04-24创建2 目录目录4 辅助功能设计14 1目的 本文主要介绍利用Qt实现局域网通信的主要实现流程和一些技术知识点的设计说明. ...

  2. qt中socket通信流程图_使用QT实现简单的tcp/ip通信

    使用QT实现tcp/ip的通信非常的简单,下面我将直接贴出代码: 一.服务器端 1.头文件#ifndef SERVERWIDGET_H #define SERVERWIDGET_H #include ...

  3. Qt网络应用----socket通信例子

    1.我们新建Qt4 Gui Application,工程名为"udpone",选中QtNetwork模块,Base class选择QMainWindow.(说明:如果一些Qt Cr ...

  4. Qt使用socket通信时接收的汉字信息显示时乱码

    显示乱码的原因是因为编码格式不一致. 下面附上一个曾经的例子. QString str = ui->textEdit->toPlainText();QByteArray text = st ...

  5. QT - 创建UDP Socket通信

    1.UDP概述 相对与TCP通信,UDP通信是面向无连接的,也即服务器端与客户端不需要建立连接即可发送接收数据. UDP的通信特点:简单轻便.不可靠.面向数据报.无连接的传输协议,可以应用在可靠性不是 ...

  6. python udp创建addr_python高级:8.socket通信part1

    0.前言 如果可以的话,请先关注(专栏和账号),然后点赞和收藏,最后学习和进步.你的支持是我继续写下去的最大动力,个人定当倾囊而送,不负众望.谢谢!!! 1.前提 基于win10专业版64位系统+64 ...

  7. 基于MFC平台实现SOCKET通信

    一.就先谈谈MFC MFC是Microsoft Foundation Classes的缩写,是由微软公司提供的一个类库,这是来帮助你完成图形界面的设计和软件平台的开发,但是不管是你软件的开发还是图形界 ...

  8. Qt网路与通信(获取本机IP、MAC、IPV6子网掩码等网络信息)

    Qt网路与通信(获取本机网络信息) 在网络应用中,经常需要获取本机的主机名/IP地址和硬件地址信息等网络信息.运用QHostInfo.QNetworkInterface.QNetworkAddress ...

  9. 多路双向串口转网口上位机C++源代码带主动连接支持UDP和TCP客户端Socket通信C语言

    多路双向串口转网口上位机C++源代码带主动连接支持UDP和TCP客户端Socket通信C语言 使用说明介绍 1.功能介绍: 完成了多路网口和串口数据转换的功能. 可实现串口接收到的数据,通过网口发送出 ...

最新文章

  1. iis占用服务器内存,W3wp.exe 进程占用内存高消耗CPU近100%导致网站反应速度缓慢的解决方案...
  2. LSTM implementation explained
  3. 日志挖掘(logminer)
  4. javase中的super、this和protected关键字
  5. 360浏览器 - 自定义切换内核 meta标签 总结
  6. python docx 合并文档 图片_使用python抓取大量简历文档内数据(word:docx;pdf;图片等)输出表格文件...
  7. C#仿QQ皮肤-Label与ListBox 控件实现----寻求滚动条的解决方案
  8. PTA-1015——Reversible Primes
  9. 汉风西游辅助使用方法(此方法适用于红手指虚拟云手机和电脑雷电模拟器)
  10. 2019年互联网寒冬,带你走进真实的面试杀出重围
  11. 提示猜数字范围python_Python 猜数字游戏
  12. 操作系统 第六章输入输出系统(自我总结式)
  13. Python报错:ImportError cannot import name ‘imresize‘
  14. 如何规划与实施数字化工厂?
  15. 一男老师每日百词转载+连载(2)
  16. 一些做“飞卡智能车”时候的总结
  17. mysql某一列 赋值_[MySQL]定时把某一列值赋值给另一列
  18. ps磨皮美容插件:Beauty Retouch Panel Mac(支持ps2021)
  19. 公众账号取名的技巧与忌讳?
  20. JSP的内置对象有哪些?

热门文章

  1. 如何将低压精密运算放大器的性能扩展到高压高侧电流检测应用(高电流电阻采集电压电路图及误差分析)
  2. 小牛带你nginx反向代理中神奇的斜线
  3. 构建增强现实移动应用程序的六款顶级工具
  4. 中国工程院院士:物联网市场须走出碎片化
  5. sudo with no password
  6. hibernate管理实体的三个状态
  7. [JavaScript]只需一行代码,轻松搞定快捷留言功能
  8. UVALive - 7511 Multiplication Table(暴力+模拟)
  9. HYSBZ - 2565 最长双回文串(回文自动机)
  10. HDU - 4569 Special equations(同余模定理)