use std::collections::{BTreeMap, HashMap};
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::net::SocketAddr;
#[derive(Debug, Clone)]
pub struct ZeroCopyTcpSocket {
stream: Arc<Mutex<TcpStream>>,
send_buffer: Arc<Mutex<Vec<u8>>>,
#[allow(dead_code)]
buffer_size: usize,
stats: Arc<Mutex<ZeroCopyStats>>,
}
#[derive(Debug, Clone, Default)]
pub struct ZeroCopyStats {
pub zero_copy_bytes_sent: u64,
pub traditional_bytes_sent: u64,
pub zero_copy_sends: u64,
pub traditional_sends: u64,
}
impl ZeroCopyTcpSocket {
pub fn new(stream: TcpStream, buffer_size: usize) -> Self {
let mut socket = Self {
stream: Arc::new(Mutex::new(stream)),
send_buffer: Arc::new(Mutex::new(Vec::with_capacity(buffer_size))),
buffer_size,
stats: Arc::new(Mutex::new(ZeroCopyStats::default())),
};
socket.apply_tcp_optimizations();
socket
}
pub fn connect(addr: &str) -> std::io::Result<Self> {
let stream: _ = TcpStream::connect(addr)?;
Ok(Self::new(stream, 64 * 1024)) }
pub fn listen(addr: &str) -> std::io::Result<TcpListener> {
TcpListener::bind(addr)
}
pub fn accept(listener: &TcpListener) -> std::io::Result<(Self, std::net::SocketAddr)> {
let (stream, addr) = listener.accept()?;
Ok((Self::new(stream, 64 * 1024), addr))
}
fn apply_tcp_optimizations(&mut self) {
if let Ok(stream) = self.stream.lock() {
let _: _ = stream.set_nodelay(true);
let _: _ = stream.set_write_timeout(Some(Duration::from_secs(30)));
}
}
pub fn send_zero_copy(&self, data: &[u8]) -> std::io::Result<usize> {
#[allow(unused_assignments)]
let mut sent_bytes = data.len();
{
let mut buffer = self.send_buffer.lock().unwrap();
buffer.clear();
buffer.extend_from_slice(data);
}
{
let mut stream = self.stream.lock().unwrap();
sent_bytes = stream.write(data)?;
}
{
let mut stats = self.stats.lock().unwrap();
stats.zero_copy_bytes_sent += sent_bytes as u64;
stats.zero_copy_sends += 1;
}
Ok(sent_bytes)
}
pub fn read(&self, buffer: &mut [u8]) -> std::io::Result<usize> {
let mut stream = self.stream.lock().unwrap();
stream.read(buffer)
}
pub fn local_addr(&self) -> std::io::Result<std::net::SocketAddr> {
let stream: _ = self.stream.lock().unwrap();
stream.local_addr()
}
pub fn peer_addr(&self) -> std::io::Result<std::net::SocketAddr> {
let stream: _ = self.stream.lock().unwrap();
stream.peer_addr()
}
pub fn set_timeout(&self, timeout: Option<Duration>) -> std::io::Result<()> {
let stream: _ = self.stream.lock().unwrap();
stream.set_read_timeout(timeout)?;
stream.set_write_timeout(timeout)?;
Ok(())
}
pub fn get_stats(&self) -> ZeroCopyStats {
self.stats.lock().unwrap().clone()
}
pub fn reset_stats(&self) {
let mut stats = self.stats.lock().unwrap();
*stats = ZeroCopyStats::default();
}
}
impl Write for ZeroCopyTcpSocket {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.send_zero_copy(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
let mut stream = self.stream.lock().unwrap();
stream.flush()
}
}
impl Read for ZeroCopyTcpSocket {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let mut stream = self.stream.lock().unwrap();
stream.read(buf)
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_zero_copy_tcp_socket_basic() {
println!("ZeroCopyTcpSocket basic test placeholder");
println!("This test requires a running TCP server to fully validate");
}
}