Server

Struct Server 

Source
pub struct Server<const BUFFER_SIZE: usize> { /* private fields */ }

Implementations§

Source§

impl<const BUFFER_SIZE: usize> Server<BUFFER_SIZE>

Source

pub fn bind( address: SocketAddr, read_timeout: Duration, ) -> Result<Self, ServerError>

Examples found in repository?
examples/simple.rs (line 91)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn address(&self) -> SocketAddr

Returns the address that the server is listening on this is the address that the server is bound to

Source

pub fn get_client_info(&self, client_id: ClientID) -> Option<ServerClientInfo>

Return client information

Examples found in repository?
examples/simple.rs (line 119)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn is_valid_client(&self, client_id: ClientID) -> bool

Check whether or not a client id matches a valid connected client

Examples found in repository?
examples/simple.rs (line 137)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn clients(&self) -> Vec<ClientID>

Return all the connected client IDs

Examples found in repository?
examples/simple.rs (line 134)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn is_running(&self) -> bool

Returns true if the server is still running (not stopped)

Examples found in repository?
examples/simple.rs (line 96)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn stop(&mut self) -> Result<(), ServerError>

Stops the server

Examples found in repository?
examples/simple.rs (line 166)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn send( &self, client_id: ClientID, protocol: Protocol, data: &[u8], ) -> Result<(), ServerError>

Send data to a client

Examples found in repository?
examples/simple.rs (lines 122-130)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn recv( &self, client_id: ClientID, protocol: Protocol, ) -> Result<Option<([u8; BUFFER_SIZE], usize)>, ServerError>

Receive data from a client and also return the size

Examples found in repository?
examples/simple.rs (line 148)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn flush(&self) -> Result<(), ServerError>

Flush all queued tasks

Examples found in repository?
examples/simple.rs (line 105)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn kick(&mut self, client_id: ClientID) -> Result<(), ServerError>

Kick a client

Examples found in repository?
examples/simple.rs (line 162)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}
Source

pub fn new_clients(&mut self) -> Result<Vec<ClientID>, ServerError>

Returns new clients’ IDs

Examples found in repository?
examples/simple.rs (line 113)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88    println!("Starting server...");
89
90    // Creating the server and binding it to a local address to listen on.
91    let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93    // Server loop.
94    loop {
95        // Check to see if the server is still running.
96        if server.is_running() == false {
97            break;
98        }
99
100        // Flush the server.
101        //
102        // I just now, as I was writing this comment, realized
103        // that you are flushing using a handle to the underlying
104        // TCP stream! Ha! Flushing... using a handle! :D
105        server.flush()?;
106
107        // There is a separate thread that accepts incoming client
108        // connections, and this function simply gets a list of
109        // any client IDs for clients that joined since the last call
110        // of this function. If this function was never called, it
111        // will return all clients, which means this function is guarenteed
112        // to return all client IDs through out the runtime of the program.
113        let new_clients = server.new_clients()?;
114
115        // Just iterating through all the new clients and welcoming them.
116        for client_id in new_clients {
117            // This should always return Some(...) since the client ID
118            // is guarenteed to be a valid client's ID.
119            let client_info = server.get_client_info(client_id).unwrap();
120
121            println!("New client {}: {}", client_id.id, client_info.client_address);
122            server.send(
123                client_id,
124                protocol,
125                format!(
126                    "Hello client #{}! Your address is: {}",
127                    client_id.id,
128                    client_info.client_address,
129                ).as_bytes(),
130            )?;
131        }
132
133        // Iterate through every client connected to the server.
134        for client_id in server.clients() {
135            // If this returns false, this is most likely because the
136            // server kicked this client in a previous iteration.
137            if server.is_valid_client(client_id) == false {
138                println!("Invalid client, skipping... (#{})", client_id.id);
139
140                continue;
141            }
142
143            // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144            // of programming languages, this library's recv() function is non-blocking,
145            // so it returns either data or nothing.
146            // The read timeout (discussed earlier) is for the blocking recv() call in the
147            // reading thread so the reading thread doesn't get stuck.
148            if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149                // The reason that a slice of the raw bytes as opposed to the whole
150                // thing is being used is because the string will actually have a lot
151                // of termination characters at the end since the raw bytes message
152                // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153                // this string will only be made with bytes that were received as opposed
154                // to the entire buffer.
155                let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157                println!("<Client #{}> {}", client_id.id, message);
158
159                match message.as_str() {
160                    "quit" => {
161                        println!("Kicking client #{}...", client_id.id);
162                        server.kick(client_id)?;
163                    },
164                    "stop" => {
165                        println!("Stopping server...");
166                        server.stop()?;
167                    },
168                    "protocol" => {
169                        println!("Protocol: {:?}", protocol);
170                    },
171                    _ => (),
172                };
173            }
174        }
175    }
176
177    Ok(())
178}

Trait Implementations§

Source§

impl<const BUFFER_SIZE: usize> Debug for Server<BUFFER_SIZE>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<const BUFFER_SIZE: usize> Freeze for Server<BUFFER_SIZE>

§

impl<const BUFFER_SIZE: usize> RefUnwindSafe for Server<BUFFER_SIZE>

§

impl<const BUFFER_SIZE: usize> Send for Server<BUFFER_SIZE>

§

impl<const BUFFER_SIZE: usize> Sync for Server<BUFFER_SIZE>

§

impl<const BUFFER_SIZE: usize> Unpin for Server<BUFFER_SIZE>

§

impl<const BUFFER_SIZE: usize> UnwindSafe for Server<BUFFER_SIZE>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.