diff --git a/tcp/Cargo.lock b/tcp/Cargo.lock index 4f972fe..c02aab0 100644 --- a/tcp/Cargo.lock +++ b/tcp/Cargo.lock @@ -2,6 +2,61 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "libc" +version = "0.2.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nix" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + [[package]] name = "tcp" version = "0.1.0" +dependencies = [ + "nix", +] diff --git a/tcp/Cargo.toml b/tcp/Cargo.toml index 490b73d..5b4fa00 100644 --- a/tcp/Cargo.toml +++ b/tcp/Cargo.toml @@ -4,3 +4,12 @@ version = "0.1.0" edition = "2024" [dependencies] +nix = { version = "0.31.2", features = ["socket", "net", "poll"] } + +[[bin]] +name = "server" +path = "src/bin/server.rs" + +[[bin]] +name = "client" +path = "src/bin/client.rs" diff --git a/tcp/src/bin/client.rs b/tcp/src/bin/client.rs new file mode 100644 index 0000000..269c454 --- /dev/null +++ b/tcp/src/bin/client.rs @@ -0,0 +1,50 @@ +// src/client.rs + +use nix::sys::socket; +use std::os::fd::AsRawFd; + +fn main() { + let tcp_soc_client = socket::socket( + socket::AddressFamily::Inet, + socket::SockType::Stream, + socket::SockFlag::empty(), + socket::SockProtocol::Tcp + ).unwrap(); + loop { + match socket::connect( + tcp_soc_client.as_raw_fd(), + &socket::SockaddrIn::new(0,0,0,0,8001) + ) { + Ok(()) => break, + Err(e) => { + println!("Connect failed: {}, retrying...", e); + std::thread::sleep(std::time::Duration::from_secs(1)); + } + } + } + + let mut i = 0; + let mut buf = [0u8; 7]; + loop { + if i > 99 { + i = 0 + } + let string = format!("ahoj {}", i); + let s = string.as_bytes(); + socket::send( + tcp_soc_client.as_raw_fd(), + s, + socket::MsgFlags::empty() + ); + + socket::recv( + tcp_soc_client.as_raw_fd(), + &mut buf, + socket::MsgFlags::empty() + ); + println!("{:?}", std::str::from_utf8(&buf).unwrap_or("")); + + i += 1; + std::thread::sleep(std::time::Duration::from_secs(1)); + } +} diff --git a/tcp/src/bin/server.rs b/tcp/src/bin/server.rs new file mode 100644 index 0000000..59a4388 --- /dev/null +++ b/tcp/src/bin/server.rs @@ -0,0 +1,69 @@ +// src/main.rs + +use nix::sys::socket; +use nix::poll; +use nix::sys::socket::MsgFlags; +use std::os::fd::FromRawFd; +use std::os::fd::AsRawFd; +use std::os::fd::AsFd; + +fn main() { + let tcp_soc = socket::socket( + socket::AddressFamily::Inet, + socket::SockType::Stream, + socket::SockFlag::SOCK_NONBLOCK, + socket::SockProtocol::Tcp + ).unwrap(); + println!("Socket created: {:?}", tcp_soc); + let rawfd = tcp_soc.as_raw_fd(); + let binded = socket::bind( + rawfd, + &socket::SockaddrIn::new(0,0,0,0,8001) + ).unwrap(); + println!("Bind: {:?}", binded); + let listening = socket::listen( + &tcp_soc, + socket::Backlog::MAXALLOWABLE + ).unwrap(); + println!("Listening: {:?}", listening); + + // waiting in here until socket becomes readable + let pollfd = poll::PollFd::new(tcp_soc.as_fd(), poll::PollFlags::POLLIN); + let mut fds = [pollfd]; + let accepted; + loop { + poll::poll(&mut fds, poll::PollTimeout::NONE).unwrap(); + let revents = fds[0].revents(); // what happened? + + if revents.unwrap().contains(poll::PollFlags::POLLIN) { + accepted = socket::accept(rawfd).unwrap(); + println!("Accepted: {:?}", accepted); + break; + } + } + + let client_fd = unsafe { std::os::fd::OwnedFd::from_raw_fd(accepted) }; + let pollfd2 = poll::PollFd::new(client_fd.as_fd(), poll::PollFlags::POLLIN); + let mut fds2 = [pollfd2]; + + loop { + poll::poll(&mut fds2, poll::PollTimeout::NONE).unwrap(); + let mut buf = [0u8; 7]; + let received = socket::recv( + accepted, + &mut buf, + MsgFlags::empty() + ).unwrap(); + if received != 0 { + // println!("Recv: {}", received); + // println!("Bytes: {:?}", buf); + // println!("Recv msg: {:?}", std::str::from_utf8(&buf).unwrap_or("")); + socket::send( + accepted, + &buf, + MsgFlags::empty() + ); + } + } + +} diff --git a/tcp/src/main.rs b/tcp/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/tcp/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}