Laminar多人 fps 游戏 UDP 协议

联合创作 · 2023-09-29 06:57

Laminar 是一种应用级传输协议,为快节奏的 fps 游戏提供基于 UDP 的可配置可靠性和排序保证,且提供轻量级的界面。

它的灵感来自 Gaffer on Games,功能类似 RakNet, Steam Socket, netcode.io。通过 Rust 写的低级 UDP 协议来支持多人游戏联网功能(尤其是 FPS 游戏),Laminar 一般用于 Amethyst 游戏引擎,不过没它也能用。

特性:

  • 碎片化
  •  不可靠的数据包
  •  不可靠的排序数据包
  •  可靠的无序数据包
  •  可靠有序的数据包
  •  可靠的排序数据包
  •  Rtt 估算
  •  协议版本监控
  •  基本连接管理
  •  Heartbeat
  •  基础的 DoS 缓冲
  •  高时序控制
  •  协议版本控制
  •  集成和单元测试良好
  •  可以被多个线程使用(Sender, Receiver)

协议

  • 握手协议
  • 高级连接管理
  • 密码密匙体系(Cryptography
  • 拥塞控制

用例:

UDP API - 发送数据

use laminar::{Socket, Packet};

// Creates the socket
let mut socket = Socket::bind("127.0.0.1:12345")?;
let packet_sender = socket.get_packet_sender();
// Starts the socket, which will start a poll mechanism to receive and send messages.
let _thread = thread::spawn(move || socket.start_polling());

// Bytes to sent
let bytes = vec![...];

// Creates packets with different reliabilities
let unreliable = Packet::unreliable(destination, bytes);
let reliable = Packet::reliable_unordered(destination, bytes);

// Specifies on which stream and how to order our packets, check out our book and documentation for more information
let unreliable = Packet::unreliable_sequenced(destination, bytes, Some(1));
let reliable_sequenced = Packet::reliable_sequenced(destination, bytes, Some(2));
let reliable_ordered = Packet::reliable_ordered(destination, bytes, Some(3));

// Sends the created packets
packet_sender.send(unreliable).unwrap();
packet_sender.send(reliable).unwrap();
packet_sender.send(unreliable_sequenced).unwrap();
packet_sender.send(reliable_sequenced).unwrap();
packet_sender.send(reliable_ordered).unwrap();

UDP API - 接收数据

use laminar::{SocketEvent, Socket};

// Creates the socket
let mut socket = Socket::bind("127.0.0.1:12346")?;
let event_receiver = socket.get_event_receiver();
// Starts the socket, which will start a poll mechanism to receive and send messages.
let _thread = thread::spawn(move || socket.start_polling());

// Waits until a socket event occurs
let result = event_receiver.recv();

match result {
    Ok(socket_event) => {
        match socket_event {
            SocketEvent::Packet(packet) => {
                let endpoint: SocketAddr = packet.addr();
                let received_data: &[u8] = packet.payload();
            }
            SocketEvent::Connect(connect_event) => { /* a client connected */ }
            SocketEvent::Timeout(timeout_event) => { /* a client timed out */ }
            SocketEvent::Disconnect(disconnect_event) => { /* a client disconnected */ }
        }
    }
    Err(e) => {
        println!("Something went wrong when receiving, error: {:?}", e);
    }
}
浏览 7
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报