Mio: how to monitor two sockets in event_loop ..?


#1

how can i monitor two sockets in event loop . like i want to get data from client connected to server through TcpListener and transfer that data to anathor server through TcpStream. help me please


#2

You asked the same question before: Mio : How can i register server socket and client socket in a same event_loop and also on stackoverflow: http://stackoverflow.com/questions/34001114/how-can-i-create-a-tcpsocket-and-tcpstream-in-the-same-mio-event-loop

Have you tried any of the stackoverflow hints? What is the code you have tried so far?


#3

i’m working on it since last 7 day’s but still i’m not able to do that. it gives me error when i try to handle TcpStream Socket in event loop for Token(1) as Client for Server C form server B.


#4

You should still not open a new post with the same question, but instead bump your old question.


Without your code (or at least the error message) there’s not much we can do.


#5

I have tried to but this will give me error like

Compiling mio v0.5.0 (file:///home/harry/workspace/test)
src/main.rs:64:22: 64:61 error: no method named `try_read_buf` found for type `core::option::Option<(mio::net::tcp::TcpStream, std::net::addr::SocketAddr)>` in the current scope
src/main.rs:64                 sock.try_read_buf(self.state.mut_read_buf());
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:64:22: 64:61 note: the method `try_read_buf` exists but the following trait bounds were not satisfied: `core::option::Option<(mio::net::tcp::TcpStream, std::net::addr::SocketAddr)> : std::io::Read`
error: aborting due to previous error
Could not compile `mio`.

To learn more, run the command again with --verbose.

help me please.

extern crate mio;
extern crate bytes;

#[macro_use]
extern crate log;
extern crate env_logger;
extern crate tempdir;

use mio::*;
use bytes::{Buf, Take};
use mio::tcp::*;
use bytes::SliceBuf;
use std::io::Cursor;


const SERVER: Token = Token(0);
const SERVER_A: Token = Token(1);

struct TestHandler {
    server: TcpListener,
    server_a: TcpStream,
    state: State,
}

enum State{
    Reading(Vec<u8>),

    Writing(Take<Cursor<Vec<u8>>>),

    Closed,
}

impl State {

    fn mut_read_buf(&mut self) -> &mut Vec<u8>{

        match *self {
            State::Reading(ref mut buf) => buf,

            _ => panic!("connection  not in reading state"),
        }
    }
}



impl TestHandler {
    fn new(srv: TcpListener, ser_a: TcpStream) -> TestHandler {
        TestHandler {
            server: srv,
            server_a: ser_a,
            state: State::Reading(vec![]),
        }
    }

    fn handle_read(&mut self, event_loop: &mut EventLoop<TestHandler>, token: Token, _: EventSet) {
        match token {
            SERVER => {
                trace!("handle_read; token=SERVER");
                let mut sock = self.server.accept().unwrap();
                //  sock.try_write_buf(&mut SliceBuf::wrap("foobar".as_bytes())).unwrap();
                     //sock.try_write_buf(&mut buffer).unwrap();

                sock.try_read_buf(self.state.mut_read_buf());

                println!("i'm in server token");
            }
            SERVER_A => {
                trace!("handle_read; token=CLIENT");
                event_loop.reregister(&self.server_a, SERVER_A, EventSet::writable(), PollOpt::level()).unwrap();
                println!("i'm in clinet token");

            }
            _ => panic!("unexpected token"),
        }
    }

    fn handle_write(&mut self, event_loop: &mut EventLoop<TestHandler>, token: Token, _: EventSet) {

        assert!(token == SERVER_A, "unexpected token {:?}", token);

    }
}

impl Handler for TestHandler {
    type Timeout = usize;
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<TestHandler>, token: Token, events: EventSet) {
        if events.is_readable() {
            println!("i'm in Read event " );
            self.handle_read(event_loop, token, events);
        }

        if events.is_writable() {
            println!("i'm in write eventuil" );

            self.handle_write(event_loop, token, events);
        }
    }

    fn timeout(&mut self, event_loop: &mut EventLoop<TestHandler>, _: usize) {
        trace!("timeout");
        event_loop.shutdown();
    }
}


pub fn main() {
    debug!("Starting TEST_REGISTER_DEREGISTER");
    let mut event_loop = EventLoop::new().unwrap();

    println!("this is middle server");
    println!("Codename: CHOCE_ME_ON_CODE\n ");

    let addr = "172.18.1.87:8482".parse().unwrap();

    let server = TcpListener::bind(&addr).unwrap();

    info!("register server socket");
    event_loop.register(&server, SERVER, EventSet::readable(), PollOpt::edge()).unwrap();

        //SERVER_A address to connect to the server A
    let addrA = "192.168.25.215:8482".parse().unwrap();
    let server_a = TcpStream::connect(&addrA).unwrap();

    // Register client socket only as writable
    event_loop.register(&server_a, SERVER_A, EventSet::readable(), PollOpt::level()).unwrap();

    let mut handler = TestHandler::new(server, server_a);

    // Start the event loop
    event_loop.run(&mut handler).unwrap();

}


Thank you


#6

it sounds to me like you should check if the sock variable is Some (see https://doc.rust-lang.org/stable/book/error-handling.html#the-option-type for details on the Option type). And then you get a tuple of a TcpStream and a SocketAddr. You should be calling the try_read_buf method only on the TcpStream object. See https://doc.rust-lang.org/stable/book/primitive-types.html#tuples on how to work with tuples.