24UDP通信
使用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通信的更多相关文章
- 理解加密算法(三)——创建CA机构,签发证书并开始TLS通信
接理解加密算法(一)--加密算法分类.理解加密算法(二)--TLS/SSL 1 不安全的TCP通信 普通的TCP通信数据是明文传输的,所以存在数据泄露和被篡改的风险,我们可以写一段测试代码试验一下. ...
- 笔记:Binder通信机制
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
- .NET 串口通信
这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...
- MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...
- 多线程的通信和同步(Java并发编程的艺术--笔记)
1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递. 2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...
- 搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 (1)
搭建QQ聊天通信的程序:(1)基于 networkcomms.net 创建一个WPF聊天客户端服务器应用程序 原文地址(英文):http://www.networkcomms.net/creating ...
- 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1
HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...
- TCP通信
//网络套接字编程实例,服务器端,TCP通信. #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #inc ...
- JAVA通信系列一:Java Socket技术总结
本文是学习java Socket整理的资料,供参考. 1 Socket通信原理 1.1 ISO七层模型 1.2 TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...
随机推荐
- 【Base64】用 js 编 解 码 base64
理论补充: Base64是一种基于64个可打印字符来表示二进制数据的表示方法. 由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符. 三个字节有24个比特,对应于4个Base64单 ...
- Delphi 有关的网址
1. 博客园 (张志峰) http://www.cnblogs.com/zhangzhifeng/ 2. CSDN Delphi论坛 https://bbs.csdn.net/ ...
- Chrome浏览器下CSS字体大小设置小于12px无效问题
当字体大小被设置小于12px时,IE.firefox可以起作用.但chrome中仍然显示为12px大小. 解决方法为: html, body { -webkit-text-size-adjus ...
- 从CES看2016物联网发展趋势
[导读] 美国时间1月6号,千呼万唤始出来的2016年国际消费电子展(CES2016)在拉斯维加斯正式拉开序幕.三天会展完满落幕,这个被誉为全球消费电子技术风向标的北美最大消费电子展俨然变成了未来智慧 ...
- 三、微信小游戏开发 --- 小游戏API调用Platform
微信小游戏API Platform主要是Egret用于来调用平台的SDK的. 在Egret中使用接口定义Platform. Egret项目中默认的platform值是DebugPlatform. 发布 ...
- c# winform窗体边框风格的设计
1.首先,窗体的FormBorderStyle设置成None,不要控制边框. 2.然后,TransparencyKey和BackColor颜色设置成相同的,这样,窗体就透明了. 3.最后,窗体的拖动 ...
- SSH电力项目二
底层方法封装(CommonDaoImpl类) public class CommonDaoImpl<T> extends HibernateDaoSupport implements IC ...
- 170630、springboot编程之普通类中调用spring管理的bean对象
我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,想直接使用 ...
- Educational Codeforces Round 28
A. Curriculum Vitae 题目链接:http://codeforces.com/contest/846/problem/A 题目意思:给你一个只包含0-1的数组,现在要求去可以去掉一些元 ...
- New Garbage Collector http://wiki.luajit.org/New-Garbage-Collector
New Garbage Collector http://wiki.luajit.org/New-Garbage-Collector GC Algorithms This is a short ove ...