This commit is contained in:
nora 2022-04-01 22:39:04 +02:00
parent 69f9a54164
commit 398a2dc2d6
2 changed files with 34 additions and 16 deletions

View file

@ -1,6 +1,7 @@
use std::{
io,
io::{Read, Write},
time::Duration,
};
use survey::sync_tcp::{SyncTcpListener, SyncTcpStream};
@ -20,11 +21,12 @@ pub fn main() {
pub fn listener() -> io::Result<()> {
let mut threads = Vec::new();
let mut listener = SyncTcpListener::bind_any(PORT)?;
let listener = SyncTcpListener::bind_any(PORT)?;
println!("Bound listener on port {PORT}");
for stream in listener.accept() {
for stream in listener.incoming() {
let stream = stream?;
let handle = std::thread::spawn(move || handler_thread(stream));
threads.push(handle);
}
@ -53,11 +55,6 @@ fn handler(mut stream: SyncTcpStream) -> io::Result<()> {
stream.write_all(b"\nAh, it's: '")?;
stream.write_all(&buf)?;
stream.write_all(b"'. I like them too owo")?;
println!("written stuff");
std::thread::sleep(Duration::from_millis(100));
Ok(())
}
fn format_addr(addr: libc::in_addr) -> String {
let bytes = addr.s_addr.to_be_bytes();
format!("{}.{}.{}.{}", bytes[0], bytes[1], bytes[2], bytes[3])
}

View file

@ -49,14 +49,15 @@ impl SyncTcpListener {
Ok(Self { fd: socket, addr })
}
pub fn accept(&mut self) -> impl Iterator<Item = SyncTcpStream> + '_ {
std::iter::from_fn(|| {
pub fn incoming(self) -> impl Iterator<Item = io::Result<SyncTcpStream>> {
std::iter::from_fn(move || {
let _ = &self; // capture self
let mut peer_sockaddr = MaybeUninit::uninit();
let mut sockaddr_size = 0;
let fd =
unsafe { libc::accept(self.fd, peer_sockaddr.as_mut_ptr(), &mut sockaddr_size) };
if fd == -1 {
return None;
return Some(Err(io::Error::last_os_error()));
}
let peer_sockaddr = unsafe {
@ -66,7 +67,7 @@ impl SyncTcpListener {
.read()
};
Some(SyncTcpStream { fd, peer_sockaddr })
Some(Ok(SyncTcpStream { fd, peer_sockaddr }))
})
}
}
@ -77,6 +78,15 @@ impl Drop for SyncTcpListener {
}
}
impl Debug for SyncTcpListener {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SyncTcpListener")
.field("fd", &self.fd)
.field("peer_addr", &format_addr(self.addr))
.finish()
}
}
pub struct SyncTcpStream {
fd: unix::io::RawFd,
peer_sockaddr: libc::sockaddr_in,
@ -94,7 +104,7 @@ impl Read for SyncTcpStream {
impl Write for SyncTcpStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let size = unsafe { libc::write(self.fd, buf.as_ptr().cast(), buf.len()) };
let size = unsafe { libc::send(self.fd, buf.as_ptr().cast(), buf.len(), 0) };
if size == -1 {
return Err(io::Error::last_os_error());
}
@ -102,13 +112,16 @@ impl Write for SyncTcpStream {
}
fn flush(&mut self) -> io::Result<()> {
todo!()
Ok(())
}
}
impl Drop for SyncTcpStream {
fn drop(&mut self) {
unsafe { libc::close(self.fd) };
unsafe {
libc::shutdown(self.fd, libc::SHUT_RDWR);
libc::close(self.fd);
};
}
}
@ -116,7 +129,15 @@ impl Debug for SyncTcpStream {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SyncTcpStream")
.field("fd", &self.fd)
.field("peer_addr", &format_addr(self.peer_sockaddr.sin_addr))
.field("peer_addr", &format_addr(self.peer_sockaddr))
.finish()
}
}
fn format_addr(addr: libc::sockaddr_in) -> String {
let bytes = addr.sin_addr.s_addr.to_be_bytes();
format!(
"{}.{}.{}.{}:{}",
bytes[0], bytes[1], bytes[2], bytes[3], addr.sin_port
)
}