通过在多个UDP套接字上侦听来避免数据包类型检查

问题描述 投票:0回答:1

简介

我有一个基本的服务器/客户端UDP设置。我希望能够避免在有效负载内发送数据包的类型(字节大小优化),并通过额外的检查来确定它是哪种类型的数据包,从而优化在两个端点上的每个数据包的编组,因此它知道要解组的类型(计算优化)。

这些数据包(或消息)的封送是使用协议缓冲区完成的。

已知解决方案

此问题的公认答案提出了三种解决方案,我目前正在使用其中一种:

Protocol buffers detect type from raw message

然而,数据包将以高频率流向网络,我觉得额外的检查和有效载荷会变得很昂贵。

为了详细说明为什么值得进行数据包大小优化,这是我的.proto文件中定义的消息。

message Packet {
    OpCode opCode = 1;
    google.protobuf.Any data = 2;
}

因此OpCode是定义包类型的变量,Any是可以是任何东西的通用对象。因此,当我解组此类数据包时,实际上是在做两次。一次是针对基本消息,另一次是基于AnyOpCode。这也意味着我需要始终确定整个数据包的缓冲区大小。如果我可以避免嵌套的通用对象并直接按已知类型发送,那么它可能会大大减少数据包的大小(取决于protobuf在后台实际执行的操作)。

建议的解决方案

我最初的想法来自以下方面:

对于UDP,套接字API允许一个套接字从多个端点接收并发送到许多端点-由于不需要更多套接字,因此许多服务器仅使用一个套接字。 > Why a single socket in UDP servers?

这让我开始思考,我可以让服务器打开多个UDP套接字,每种套接字将通过网络,但仍然能够与许多客户端通信。

这使每个套接字始终知道要解组的数据包类型,并具有要填充的固定缓冲区大小(避免必须检查数据包的长度)。

已知限制/假设

据我了解,操作系统确实限制了可以打开的套接字数量。但是我怀疑这会影响我,因为我最多只需要18个,因为那是我要针对的数据包类型。

问题

因此,在较低的网络级别上,由于将打开多个UDP套接字,将如何处理这些打开的套接字?每个套接字是否可以同时处理传入/传出的数据包,这给我带来了额外的优化?或者,当我向18000个端点发送数据包时,它只是成为瓶颈,因为它仍然都是这个“单个UDP实体”,可能使我尝试进行优化,而不是优化……

简介,我有一个基本的服务器/客户端UDP设置。我希望能够通过避免在有效负载内发送数据包的类型来优化在两个端点上的每个数据包的编组(字节大小优化),...

sockets go udp protocol-buffers marshalling
1个回答
2
投票

每个套接字彼此独立,即具有自己的发送和接收缓冲区,并且OS内核可以并行处理这些套接字。这也意味着消息的处理顺序可能与发送或接收消息时的顺序不同,但这在您的情况下可能不是问题(使用UDP,您已经需要意识到可能会发生丢包,重复和重新排序) 。每个套接字还需要绑定到不同的<ip,port>元组(通常只有端口是不同的),如果您需要处理发送方和接收方之间的防火墙,这可能会使它更加复杂。

© www.soinside.com 2019 - 2024. All rights reserved.