tachyon/tachyon/
unreliable_sender.rs

1use std::{io, net::UdpSocket};
2
3use super::{
4    header::{Header, MESSAGE_TYPE_UNRELIABLE},
5    network_address::NetworkAddress,
6    TachyonSendResult, SEND_ERROR_CHANNEL, SEND_ERROR_LENGTH,
7};
8
9// this is created with a cloned UdpSocket which can then be used from another thread.
10// this is purely a rust thing sockets are atomic at the OS level.
11pub struct UnreliableSender {
12    pub socket: Option<UdpSocket>,
13}
14
15impl UnreliableSender {
16    pub fn send_unreliable(
17        &self,
18        address: NetworkAddress,
19        data: &mut [u8],
20        length: usize,
21    ) -> TachyonSendResult {
22        let mut result = TachyonSendResult::default();
23
24        if length < 1 {
25            result.error = SEND_ERROR_LENGTH;
26            return result;
27        }
28
29        if !self.socket.is_some() {
30            result.error = SEND_ERROR_CHANNEL;
31            return result;
32        }
33
34        let mut header = Header::default();
35        header.message_type = MESSAGE_TYPE_UNRELIABLE;
36        header.write_unreliable(data);
37
38        let sent_len = self.send_to(address, data, length);
39        result.sent_len = sent_len as u32;
40        result.header = header;
41
42        return result;
43    }
44
45    fn send_to(&self, address: NetworkAddress, data: &[u8], length: usize) -> usize {
46        match &self.socket {
47            Some(socket) => {
48                let slice = &data[0..length];
49                let socket_result: io::Result<usize>;
50
51                if address.port == 0 {
52                    socket_result = socket.send(slice);
53                } else {
54                    socket_result = socket.send_to(slice, address.to_socket_addr());
55                }
56
57                match socket_result {
58                    Ok(size) => {
59                        return size;
60                    }
61                    Err(_) => {
62                        return 0;
63                    }
64                }
65            }
66            None => {
67                return 0;
68            }
69        }
70    }
71}