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

解析:UDP无需确认对方是否在线,是否能收到。因此服务端也不需要设置监听套接字。双发只需通信套接字即可。Socket绑定指定端口号,其他客户端可以通过该端口号直接进行通信。如:服务端bind(888),而不需要绑定888,也可以直接向服务端发出信息,但是服务端无法向客户端回复(因为不知道客户端端口)。对方发出数据,立即触发信号readyRead,再利用readDatagram接收信息,writeDatagram进行发送信息。

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

1.创建套接字

2.绑定套接字,在UDP中如果需要接收数据则需要对套接字进行绑定,只发送数据则不需要对套接字进行绑定。通过调用bind()函数将套接字绑定到指定端口上。

3.接收或者发送数据

接收数据:使用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:数据接收方的端口号

TCP/IP 和 UDP的区别

TCP/IP

UDP

是否连接

面向连接

无连接

传输方式

基于流

基于数据报

传输可靠性

可靠

不可靠

传输效率

效率低

效率高

能否广播

不能

说白了,TCP就是打电话,UDP就是发短信,TCP要确认对方在线并能完整接收,再做出回应。UDP不管对方是否在线,只需最快速率发送给对方,不管对方是否能接收。

服务端

UdpServer.h

#include "udpcilent.h"

#include "ui_udpcilent.h"

UdpCilent::UdpCilent(QWidget *parent) :

QWidget(parent),

ui(new Ui::UdpCilent)

{

ui->setupUi(this);

this->setWindowTitle("服务端端口:8888");

ui->Ip->setText("127.0.0.1");

ui->Port->setText("888");

m_Client=new QUdpSocket(this);

//绑定端口号

m_Client->bind(8888);

//通信

connect(m_Client,&QUdpSocket::readyRead,

[=]()

{

char pBuf[1024]={0};

QHostAddress peerIP;

quint16 port;

//读取对方的信息,端口,IP

qint64 size=m_Client->readDatagram(pBuf,1024,&peerIP,&port);

//显示在信息框

if(size!=-1)

{

QString strTemp=QString("[%1:%2]:%3").arg(peerIP.toString()).arg(port).arg(pBuf);

ui->textEdit_2->setText(strTemp);

}

}

);

}

UdpCilent::~UdpCilent()

{

delete ui;

delete m_Client;

m_Client=NULL;

}

void UdpCilent::on_pushButton_clicked()

{

//获取要发送的信息,设置对方的IP,端口号

QString strSend=ui->textEdit->toPlainText();

QString peerIP=ui->Ip->text();

quint16 port=ui->Port->text().toInt();

//发送

m_Client->writeDatagram(strSend.toUtf8(),(QHostAddress)peerIP,port);

}

void UdpCilent::on_pushButton_2_clicked()

{

m_Client->close();

}

UdpServer.cpp

#include "UdpServer.h"

#include "ui_widget.h"

#include <QHostAddress>

#include <QDebug>

Widget::Widget(QWidget *parent) :

QWidget(parent),

ui(new Ui::Widget)

{

ui->setupUi(this);

this->setWindowTitle("服务器端口:888");

ui->Ip->setText("127.0.0.1");

ui->Port->setText("8888");

//分配空间,指定父对象

m_Server=new QUdpSocket(this);

//绑定端口号

m_Server->bind(888);

//通信

connect(m_Server,&QUdpSocket::readyRead,

[=]()

{

char pBuf[1024]={0};

QHostAddress peerIP;

quint16 port;

//读取对方的信息,端口,IP

qint64 size=m_Server->readDatagram(pBuf,sizeof(pBuf),&peerIP,&port);

//显示在信息框

if(size!=-1)

{

QString strTemp=QString("[%1:%2]:%3").arg(peerIP.toString()).arg(port).arg(pBuf);

ui->textEdit_2->append(strTemp);

}

}

);

}

Widget::~Widget()

{

delete ui;

delete m_Server;

m_Server=NULL;

}

void Widget::on_pushButton_clicked()

{

//获取要发送的信息,设置对方的IP,端口号

QString strSend=ui->textEdit->toPlainText();

QString peerIP=ui->Ip->text();

quint16 port=ui->Port->text().toInt();

//发送

m_Server->writeDatagram(strSend.toUtf8(),QHostAddress(peerIP),port);

}

void Widget::on_pushButton_2_clicked()

{

m_Server->close();

}

同一程序添加两个窗口,且有设计器。新建一个文件,但不是C++类文件,而是QT且带有界面类的,最后在main中使用show()直接显示。如下图:

客户端

UdpServer.h

#ifndef UDPSERVER_H

#define UDPSERVER_H

#include <QWidget>

#include <QUdpSocket>

namespace Ui {

class Widget;

}

class Widget : public QWidget

{

Q_OBJECT

public:

explicit Widget(QWidget *parent = 0);

~Widget();

private slots:

void on_pushButton_clicked();       //发送

void on_pushButton_2_clicked();     //关闭通信(其实没用)

private:

Ui::Widget *ui;

QUdpSocket *m_Server;   //服务器的通信套接字

};

#endif // UDPSERVER_H

udpcilent.cpp

#include "udpcilent.h"

#include "ui_udpcilent.h"

UdpCilent::UdpCilent(QWidget *parent) :

QWidget(parent),

ui(new Ui::UdpCilent)

{

ui->setupUi(this);

this->setWindowTitle("服务端端口:8888");

ui->Ip->setText("127.0.0.1");

ui->Port->setText("888");

m_Client=new QUdpSocket(this);

//绑定端口号

m_Client->bind(8888);

//通信

connect(m_Client,&QUdpSocket::readyRead,

[=]()

{

char pBuf[1024]={0};

QHostAddress peerIP;

quint16 port;

//读取对方的信息,端口,IP

qint64 size=m_Client->readDatagram(pBuf,1024,&peerIP,&port);

//显示在信息框

if(size!=-1)

{

QString strTemp=QString("[%1:%2]:%3").arg(peerIP.toString()).arg(port).arg(pBuf);

ui->textEdit_2->setText(strTemp);

}

}

);

}

UdpCilent::~UdpCilent()

{

delete ui;

delete m_Client;

m_Client=NULL;

}

void UdpCilent::on_pushButton_clicked()

{

//获取要发送的信息,设置对方的IP,端口号

QString strSend=ui->textEdit->toPlainText();

QString peerIP=ui->Ip->text();

quint16 port=ui->Port->text().toInt();

//发送

m_Client->writeDatagram(strSend.toUtf8(),(QHostAddress)peerIP,port);

}

void UdpCilent::on_pushButton_2_clicked()

{

m_Client->close();

}

main.cpp

#include "UdpServer.h"

#include <QApplication>

#include <udpcilent.h>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

Widget w;

w.show();

UdpCilent u;

u.show();

return a.exec();

}

程序结果图:

24UDP通信的更多相关文章

  1. 理解加密算法(三)——创建CA机构,签发证书并开始TLS通信

    接理解加密算法(一)--加密算法分类.理解加密算法(二)--TLS/SSL 1 不安全的TCP通信 普通的TCP通信数据是明文传输的,所以存在数据泄露和被篡改的风险,我们可以写一段测试代码试验一下. ...

  2. 笔记:Binder通信机制

    TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...

  3. .NET 串口通信

    这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...

  4. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  5. 多线程的通信和同步(Java并发编程的艺术--笔记)

    1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递.   2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...

  6. 搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 (1)

    搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 原文地址(英文):http://www.networkcomms.net/creating ...

  7. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  8. TCP通信

    //网络套接字编程实例,服务器端,TCP通信. #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #inc ...

  9. JAVA通信系列一:Java Socket技术总结

    本文是学习java Socket整理的资料,供参考. 1       Socket通信原理 1.1     ISO七层模型 1.2     TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...

随机推荐

  1. Android使用百度定位API时获取的地址信息为null

    option.setAddrType("all"); //加上这个配置后才可以取到详细地址信息

  2. 查询软件和硬件列表清单[将文章里代码另存为 list.vbs,双击运行就会出现一个html页面]

    '==========================================================================' Name: 查询软件和硬件列表清单' 不支持W ...

  3. x86 x64下调用约定浅析

    x86平台下调用约定 我们都知道x86平台下常用的有三种调用约定,__cdecl.__stdcall.__fastcall.我们分别对这三种调用约定进行分析. __cdecl __cdecl是C/C+ ...

  4. HTML5文件拖拽上传记录

    JS文件: var FileName = ""; var FileStr = ""; (function () { function $id(id) { ret ...

  5. php中关于时间的用法

    一.时间戳相关:        当前时间戳:time();         把时间戳转换为时间显示:date("Y-m-d H:i:s", $a);         把日期时间转换 ...

  6. Git学习笔记(SourceTree克隆、提交、推送、拉取等)

    学习一下sourcetree使用git 目录 一 克隆Clone 二 提交Commit和推送Push 三 拉取pull和获取fetch 四 版本回退reset 五 检出checkout 六 标签Tag ...

  7. [XML] CoolFormat

    http://files.cnblogs.com/files/wjs16/CoolFormat3.4.rar

  8. Android Studio 解决Fetching android sdk component information加载过久问题

    extends:http://www.cnblogs.com/sonyi/p/4154797.html 安装完成后,如果直接启动,Android Studio会去获取 android sdk 组件信息 ...

  9. Python - 3.6 学习三

    面向对象编程 面向对象编程 Object Oriented Programming 简称 OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程 ...

  10. 310实验室OTL问题----将写好的C++文件转换成Python文件,并将数据可视化

    如图:文件夹 第一处:optimizer文件夹下的:optimizer.h文件中添加你所写代码的头文件  #include <OTL/Optimizer/Reference-NSGA-II/Re ...