Expand description
§Rusty TPKT
A pure rust implementation of TPKT over TCP.
TPKT is a glue protocol between the ISO standard protocols and TCP (an IETF protocol).
This standard is known by many names:
- ITOT
- TPKT
- RFC 2126
This package is intended to be used in conjunction with a higher level protocol. For example:
§Using this Library
§Static Dispatch
This library uses static dispatch. This protocol is a very small slice in a large protocol stack. It is called very often. Static dispatch removes vtable lookups reducing call overhead. Static dispatch also allows the types to be resolved at compile time, giving the compiler greater scope to perform optimisations. This also makes it ideal for use in embedded devices.
The trade of is that static dispatch may be more difficult to work with in complex applications. The rusty-mms-service provides one example of going from a static dispatch to a dynamic dispatch environment without degrading performance.
§Async and STD
This library uses async rust and std components. If using this in embedded systems, FreeRTOS may be required to provide and adaption layer between embedded hardware and this library.
§Cancel Safety
Send and Recv operations are cancel safe as long as the caller does not drop their buffer after cancel if it still contains data. It is safe to call Send and Recv anytime after cancellation.
§Conformance
This library implements Class 0 functionality.
This allows most ISO protcols to be operated over this implementation, normally using the ‘kernel only’ or ‘core features’ of higher layer protocols. Please refer to the conformance statement of the standard you are using to ensure all the features you require are offered given the comformance of this implementation.
§References
§Examples
Examples may be found in the examples directory. Basic useage is shown below.
use std::{collections::VecDeque, net::SocketAddr};
use anyhow::anyhow;
use rusty_tpkt::{TcpTpktConnection, TcpTpktServer, TpktConnection, TpktReader, TpktWriter};
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let test_address = "127.0.0.1:12345".parse()?;
// Start the server first so it can open the port. We are using spawn so it starts running immediately.
let server_connect_task = tokio::task::spawn(example_server(test_address));
let client_connect_task = tokio::task::spawn(example_client(test_address));
// Check for errors.
client_connect_task.await??;
server_connect_task.await??;
Ok(())
}
async fn example_server(address: SocketAddr) -> Result<(), anyhow::Error> {
// Create the server. It will start listening on the port.
let server = TcpTpktServer::listen(address.clone()).await?;
// Accept an incoming connection. This can be called in a loop to keep accepting connections.
let connection = server.accept().await?;
// Split the connection into read and write halves. This is often done for easy multi-tasking.
let (mut reader, mut writer) = connection.split().await?;
// Get data from the client.
let data = reader.recv().await?.ok_or_else(|| anyhow!("Connection Closed"))?;
assert_eq!(data, "Hello from the client!".as_bytes().to_vec());
// Send data to the client. This uses a buffer to ensure the operation is cancel safe. Store this buffer on your object an reuse it.
let mut data = VecDeque::new();
data.push_back("Hello from the server!".as_bytes().to_vec());
while data.len() > 0 {
writer.send(&mut data).await?;
}
// The connection will be closed when it is dropped.
Ok(())
}
async fn example_client(address: SocketAddr) -> Result<(), anyhow::Error> {
// Create the client connection. This will start a connection.
let connection = TcpTpktConnection::connect(address).await?;
// Split the connection into read and write halves. This is often done for easy multi-tasking.
let (mut reader, mut writer) = connection.split().await?;
// Send data to the server. This uses a buffer to ensure the operation is cancel safe. Store this buffer on your object an reuse it.
let mut data = VecDeque::new();
data.push_back("Hello from the client!".as_bytes().to_vec());
while data.len() > 0 {
writer.send(&mut data).await?;
}
// Get data from the server.
let data = reader.recv().await?.ok_or_else(|| anyhow!("Connection Closed"))?;
assert_eq!(data, "Hello from the server!".as_bytes().to_vec());
// The connection will be closed when it is dropped.
Ok(())
}Structs§
- TcpTpkt
Connection - An established TPKT connection.
- TcpTpkt
Protocol Information - Keeps track of tpkt connection information
- TcpTpkt
Reader - The read half of a TPKT connection.
- TcpTpkt
Server - A TPKT server implemented over a TCP connection.
- TcpTpkt
Writer - The write half of a TPKT connection.
Enums§
Traits§
- Protocol
Information - Information regarding the protocol stack. This is useful for authentication and logging.
- Tpkt
Connection - A trait representing a TPKT connection. There is no distinction between a client and a server connection once they are established.
- Tpkt
Reader - A trait representing the read half of TPKT connection.
- Tpkt
Writer - A trait representing the write half of TPKT connection.