这是一种高度可移植、轻量级、简单、零成本的 UDP 套接字抽象,具有双栈 IPv4/IPv6 支持,可快速实现面向消息的协议。该库专为与 C、C++、C# 和其他语言的跨语言兼容性而设计。对于 .NET 环境,函数支持 blittable 指针作为托管类型的替代方案,以便与非托管内存分配器一起使用。
可以使用 CMake 和 GNU Make 或 Visual Studio 来构建本机库。
可以使用任何支持 C# 4.0 或更高版本的可用编译平台来构建托管程序集。
您可以从发布部分获取已编译的库。
仅针对传统平台提供二进制文件:Windows、Linux 和 macOS (x64)。
支持的操作系统版本:
在开始工作之前,应使用NanoSockets.UDP.Initialize();
功能。
工作完成后,使用NanoSockets.UDP.Deinitialize();
功能。
Socket server = UDP . Create ( 256 * 1024 , 256 * 1024 ) ;
Address listenAddress = new Address ( ) ;
listenAddress . port = port ;
if ( UDP . SetIP ( ref listenAddress , "::0" ) == Status . OK )
Console . WriteLine ( "Address set!" ) ;
if ( UDP . Bind ( server , ref listenAddress ) == 0 )
Console . WriteLine ( "Socket bound!" ) ;
if ( UDP . SetDontFragment ( server ) != Status . OK )
Console . WriteLine ( "Don't fragment option error!" ) ;
if ( UDP . SetNonBlocking ( server ) != Status . OK )
Console . WriteLine ( "Non-blocking option error!" ) ;
StringBuilder ip = new StringBuilder ( UDP . hostNameSize ) ;
Address address = new Address ( ) ;
byte [ ] buffer = new byte [ 1024 ] ;
while ( ! Console . KeyAvailable ) {
if ( UDP . Poll ( server , 15 ) > 0 ) {
int dataLength = 0 ;
while ( ( dataLength = UDP . Receive ( server , ref address , buffer , buffer . Length ) ) > 0 ) {
UDP . GetIP ( ref address , ip , ip . Capacity ) ;
Console . WriteLine ( "Message received from - IP: " + ip + ", Data length: " + dataLength ) ;
UDP . Send ( server , ref address , buffer , buffer . Length ) ;
}
}
}
UDP . Destroy ( ref server ) ;
Socket client = UDP . Create ( 256 * 1024 , 256 * 1024 ) ;
Address connectionAddress = new Address ( ) ;
connectionAddress . port = port ;
if ( UDP . SetIP ( ref connectionAddress , "::1" ) == Status . OK )
Console . WriteLine ( "Address set!" ) ;
if ( UDP . Connect ( client , ref connectionAddress ) == 0 )
Console . WriteLine ( "Socket connected!" ) ;
if ( UDP . SetDontFragment ( client ) != Status . OK )
Console . WriteLine ( "Don't fragment option error!" ) ;
if ( UDP . SetNonBlocking ( client ) != Status . OK )
Console . WriteLine ( "Non-blocking option error!" ) ;
byte [ ] buffer = new byte [ 1024 ] ;
UDP . Send ( client , IntPtr . Zero , buffer , buffer . Length ) ;
while ( ! Console . KeyAvailable ) {
if ( UDP . Poll ( client , 15 ) > 0 ) {
int dataLength = 0 ;
while ( ( dataLength = UDP . Receive ( client , IntPtr . Zero , buffer , buffer . Length ) ) > 0 ) {
Console . WriteLine ( "Message received from server - Data length: " + dataLength ) ;
UDP . Send ( client , IntPtr . Zero , buffer , buffer . Length ) ;
}
}
}
UDP . Destroy ( ref client ) ;
使用方法与.NET环境下几乎相同,只是控制台功能必须替换为Unity提供的功能。如果将在游戏循环中调用UDP.Poll()
,请确保超时参数设置为 0,这意味着非阻塞。此外,通过在播放器设置中启用适当的选项,使 Unity 在后台运行。
函数状态类型的定义:
OK
Error
包含带有套接字句柄的 blittable 结构。
Socket.handle
一个套接字句柄。
Socket.IsCreated
检查套接字是否已创建。
包含带有匿名主机数据和端口号的 blittable 结构。
Address.port
端口号。
UDP.Initialize()
初始化本机库。应在开始工作之前调用。返回状态和结果。
UDP.Deinitialize()
取消初始化本机库。工作完成后应调用。
UDP.Create(int sendBufferSize, int receiveBufferSize)
创建一个具有指定大小的缓冲区用于发送和接收的新套接字。返回带有句柄的Socket
结构。
UDP.Destroy(ref Socket socket)
销毁套接字并重置句柄。
UDP.Bind(Socket socket, ref Address address)
为套接字分配一个地址。地址参数可以设置为IntPtr.Zero
让操作系统分配任意地址。成功时返回 0,失败时返回 != 0。
UDP.Connect(Socket socket, ref Address address)
将套接字连接到某个地址。成功时返回 0,失败时返回 != 0。
UDP.SetOption(Socket socket, int level, int optionName, ref int optionValue, int optionLength)
设置与套接字关联的套接字选项的当前值。此函数可用于设置默认情况下在创建套接字时未指定的特定于平台的选项。返回状态和结果。
UDP.GetOption(Socket socket, int level, int optionName, ref int optionValue, ref int optionLength)
获取与套接字关联的套接字选项的当前值。选项值的长度应初始设置为适当的大小。返回状态和结果。
UDP.SetNonBlocking(Socket socket, bool shouldBlock)
为套接字设置非阻塞 I/O 模式。返回状态和结果。
UDP.SetDontFragment(Socket socket)
设置套接字的不分段模式。返回状态和结果。
UDP.Poll(Socket socket, long timeout)
确定套接字的状态并在必要时等待。该功能可用于面向准备的接收。超时参数可以以毫秒为单位指定,以控制轮询持续时间。如果指定超时为 0,该函数将立即返回。如果超过时间限制,它将返回 0。如果套接字已准备好接收,它将返回 1。否则,如果发生错误,它将返回 < 0。
UDP.Send(Socket socket, ref Address address, byte[] buffer, int bufferLength)
将消息发送到接收方的指定地址。如果套接字连接到某个地址,则可以将地址参数设置为IntPtr.Zero
。可以使用指向本机缓冲区的指针IntPtr
来代替对字节数组的引用。返回发送的字节总数,该总数可以小于缓冲区长度指示的数字。否则,如果发生错误,它将返回 < 0。
UDP.Receive(Socket socket, ref Address address, byte[] buffer, int bufferLength)
接收消息并获取发送者的地址。地址参数可以设置为IntPtr.Zero
以跳过地址获取。可以使用指向本机缓冲区的指针IntPtr
来代替对字节数组的引用。返回接收到的字节总数。否则,如果发生错误,它将返回 < 0。
UDP.GetAddress(Socket socket, ref Address address)
从绑定或连接的套接字获取地址。该函数对于确定操作系统已设置的本地关联特别有用。返回状态和结果。
UDP.IsEqual(ref Address left, ref Address right)
比较两个地址是否相等。返回状态和结果。
UDP.SetIP(ref Address address, string ip)
设置 IP 地址。可以使用指针IntPtr
代替不可变字符串。返回状态和结果。
UDP.GetIP(ref Address address, StringBuilder ip, int ipLength)
获取 IP 地址。可变字符串的容量应等于UDP.hostNameSize
常量字段。可以使用指针IntPtr
代替可变字符串。返回状态和结果。
UDP.SetHostName(ref Address address, string name)
设置主机名或 IP 地址。可以使用指针IntPtr
代替不可变字符串。返回状态和结果。
UDP.GetHostName(ref Address address, StringBuilder name, int nameLength)
尝试从地址进行反向查找。可以使用指针IntPtr
代替可变字符串。返回状态和结果。