Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern crate libc;
- use std::io::prelude::*;
- use std::net::{TcpStream, TcpListener, UdpSocket};
- use std::{io, mem, ptr, time};
- use std::os::unix::io::{AsRawFd, RawFd};
- use std::thread;
- use nix::unistd::{fork, ForkResult};
- pub struct FdSet(libc::fd_set);
- impl FdSet {
- pub fn new() -> FdSet {
- unsafe {
- let mut raw_fd_set = mem::MaybeUninit::<libc::fd_set>::uninit();
- libc::FD_ZERO(raw_fd_set.as_mut_ptr());
- FdSet(raw_fd_set.assume_init())
- }
- }
- pub fn clear(&mut self, fd: RawFd) {
- unsafe { libc::FD_CLR(fd, &mut self.0) }
- }
- pub fn set(&mut self, fd: RawFd) {
- unsafe { libc::FD_SET(fd, &mut self.0) }
- }
- pub fn is_set(&mut self, fd: RawFd) -> bool {
- unsafe { libc::FD_ISSET(fd, &mut self.0) }
- }
- }
- fn to_fdset_ptr(opt: Option<&mut FdSet>) -> *mut libc::fd_set {
- match opt {
- None => ptr::null_mut(),
- Some(&mut FdSet(ref mut raw_fd_set)) => raw_fd_set,
- }
- }
- fn to_ptr<T>(opt: Option<&T>) -> *const T {
- match opt {
- None => ptr::null::<T>(),
- Some(p) => p,
- }
- }
- pub fn make_timeval(duration: time::Duration) -> libc::timeval {
- libc::timeval {
- tv_sec: duration.as_secs() as i64,
- tv_usec: duration.subsec_micros() as i64,
- }
- }
- pub fn select(
- nfds: libc::c_int,
- readfds: Option<&mut FdSet>,
- writefds: Option<&mut FdSet>,
- errorfds: Option<&mut FdSet>,
- timeout: Option<&libc::timeval>,
- ) -> io::Result<usize> {
- match unsafe {
- libc::select(
- nfds,
- to_fdset_ptr(readfds),
- to_fdset_ptr(writefds),
- to_fdset_ptr(errorfds),
- to_ptr::<libc::timeval>(timeout) as *mut libc::timeval,
- )
- } {
- -1 => Err(io::Error::last_os_error()),
- res => Ok(res as usize),
- }
- }
- pub fn main(){
- let mut msg: [u8; 128] = [0; 128];
- #[allow(unused_unsafe)]
- match unsafe{fork()} {
- Ok(ForkResult::Parent { child, .. }) => {
- println!("Waiting for a while on the parent process so that listener can start on child process with pid: {}!", child);
- thread::sleep(time::Duration::from_secs(10));
- println!("Trying to connect to listener in parent. \n");
- let mut tcp_stream = TcpStream::connect("127.0.0.1:8080").expect("Error connecting to listener!");
- let udp_socket = UdpSocket::bind("127.0.0.1:8080").expect("Failed creating a client side udp socket.");
- udp_socket.connect("127.0.0.1:8081").expect("Udp connection failure");
- let rfd1 = tcp_stream.as_raw_fd();
- let rfd2 = udp_socket.as_raw_fd();
- println!("TCP Socket: {}", rfd1);
- println!("UDP Socket: {}", rfd2);
- let max_fd = rfd1.max(rfd2);
- let mut fd_set = FdSet::new();
- fd_set.set(rfd1);
- fd_set.set(rfd2);
- match select(
- max_fd + 1,
- Some(&mut fd_set), // read
- None, // write
- None, // error
- Some(&make_timeval(time::Duration::new(10, 0))), // timeout
- ) {
- Ok(res) => {
- println!("Select result: {}", res);
- if (fd_set).is_set(rfd1) {
- println!("TCP socket recieved something!");
- let bytes = tcp_stream.read(&mut msg).expect("Failed to recieve message from listener!").expect("Error reading message");
- println!("TCP Socket Recieved: {}", String::from_utf8_lossy(&msg[..bytes]));
- }
- if (fd_set).is_set(rfd2) {
- println!("UDP socket recieved something!");
- let bytes = udp_socket.recv(&mut msg).expect("Error reading message");
- println!("UDP Socket Recieved: {}", String::from_utf8_lossy(&msg[..bytes]));
- }
- }
- Err(err) => {
- println!("Failed to select: {:?}", err);
- }
- }
- }
- Ok(ForkResult::Child) => {
- println!("Starting listener in child process");
- let tcp_listener = TcpListener::bind("127.0.0.1:8080").expect("Error starting a TCP listener!");
- println!("TCP Listener started in child process.\n");
- let socket = UdpSocket::bind("127.0.0.1:8081").expect("Error starting a UDP socket");
- println!("UDP socket started in child process.\n");
- socket.connect("127.0.0.1:8080").expect("Connect to socket failed.");
- socket.send("Hello socket!".as_bytes()).expect("data broadcast on udp failed");
- println!("Listening for tcp connections");
- let mut stream = tcp_listener.incoming().next().expect("Failed to find a peer").expect("Failed to connect to reciever");
- stream.write("hello world!".as_bytes()).expect("Failed to respond");
- }
- Err(_) => println!("Fork failed"),
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement