Node学习十三 —— 用户数据报

23 篇文章 0 订阅

使用用户数据报

TCP是一个面相连接的协议,它能提供可靠有序的数据流。然而,用户数据报协议(User Datagram Protocol,UDP)是一种无连接的协议,不具备TCP的传输特性。当发送UFP数据包的时候,无法保证数据包都顺序到达,甚至无法保证它能够到达。

虽然有这些缺点,但是它还是非常有用,例如在需要广播消息的时候,并不需要严格地传输保证,或者消息顺序,此外,UDP也可用于不知道网络节点地址的场合。

1. 理解用户数据报

与TCP一样,UDP也位于传输层,在IP层之上,它允许你向其他主机发送消息,而不需要事先的通信来建立必要的传输信道或者数据路径。

与TCP不一样的,UDP不是面相连接的,没有那么高的稳定性,相反,它提供的是一种不可靠的服务。UDP假定错误检测要不没有必要,要不将错误检测放在应用层进行。

2. 理解用户数据报的使用

时间敏感应用程序通常使用UDP,因为此时丢失数据报比等待延时的数据报更合适。

UDP的无状态特性对于服务器响应来自大量的客户端的小查询同样有效,与TCP不同,UDP支持数据包的广播和多播(将数据包发送给所有订阅者)

3. 构建数据报服务器

Node使dgram模块来支持数据报。

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

dgram.createSocket函数接收套接字类型作为第一个参数,该参数是udp4(IPv4上的UDP),或udp6(IPv6上的UDP)

注意
UDP中不存在真正的服务器,他只是在套接字上监听消息的终端,此处为了便于阐述和理解。

监听消息

UDP服务器接收到消息会发射message事件,可以绑定到一个端口去接收:

const dgram = require('dgram');
const port = 1234;
const server = dgram.createSocket('udp4');

server.on('listening', () => {
	const address = peer.address();
	console.log("ADDRESS " + address.address + ":" + address.port);
})

server.bind(port);

查看附加的消息信息

除了发送消息本身之外,message事件还会把一些发送端的基本信息传入回调函数,作为第二个参数:

server.on('message', (data, info) => {
	console.log(info.address);
	console.log(info.port);
})

4. 创建简单的数据报回送服务器

接收到了消息,并且通过info可以获得源地址,那么你可以回一个消息

等待消息

等待消息就是监听message事件

回消息

server.on('message', (data,info) => {
	server.send(message,
		0,
		message.length,
		info.port,
		info.address)
})

使用send方法发送消息,它有很多参数:

  • 前三个参数对消息进行描述,第一个是缓冲区,第二个是消息的初始偏移位,最后是字节长度。
  • 后面两个是目的地的端口和地址。

5. 构建数据报客户端

创建客户端

只需要创建一个UDP套接字,就可以使用它作为客户端发送消息:

const dgram = require('dgram');
// 创建UDP套接字
const client = dgram.createSocket('udp4');

从上面可以看出,除了没有绑定端口,其余部分和创建服务器一样,使用的接口也是dgram.createSocket()。因为没有绑定特定的端口,消息会从一个随机的UDP端口发出。如果从特定端口发送,需要使用client.bind()方法。

发送消息

// 创建一个缓冲区
const msg = new Buffer('This is a message');
// 发送消息
const port = 1234;
const host = "localhost";
client.send(message,0,message.length,port,host);

关闭套接字

在上面发送消息的例子中,套接字会在消息被全部传送到网络中后被关闭,但是send()还可以接受一个回调函数,可以在回调函数中使用close()手动关闭套接字:

client.send(message,0,message.length,1234,'localhost', (err, bytes) => {
	if(err) client.close();
})

回调接受两个参数,一个是错误,一个是发送的字节数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沧州刺史

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值