Как реализовать неблокирующий опрос? - PullRequest
1 голос
/ 18 октября 2019

Приложение для чтения / записи данных через последовательный порт и TCP (порт 1502). Когда tcp-сервер получает пакет tcp, он должен отправить его через последовательный порт. Когда он получает кадр через последовательный порт, он должен отправить его через tcp. Там может быть много клиентов TCP. Код ниже не работает. Токен SERIAL_TOKEN выполняется только один раз. Почему?

extern crate mio;
extern crate mio_serial;

use std::time::Duration;
use chrono;

use mio::{
    net::{TcpListener, TcpStream},
    Events, Poll, PollOpt, Ready, Token
}; // 0.6.19

use std::{
    collections::HashMap,
    io::{self, Read, Write},
};

fn main() 
{
    let settings = mio_serial::SerialPortSettings::default();
    let port_name = "/dev/ttyS91".to_string();
    let port = mio_serial::Serial::from_path(&port_name, &settings).unwrap();

    let address = "0.0.0.0:1502";
    let listener = TcpListener::bind(&address.parse().unwrap()).unwrap();

    let poll = Poll::new().unwrap();
    const SERIAL_TOKEN: Token = Token(250);
    const TCP_SERVER_TOKEN: Token = Token(0);

    poll.register(&listener, TCP_SERVER_TOKEN, Ready::readable(), PollOpt::edge()).unwrap();
    poll.register(&port, SERIAL_TOKEN,  Ready::readable() | Ready::writable(), PollOpt::edge()).unwrap();

    let mut events = Events::with_capacity(1024);
    let mut counter: usize = 0;

    let mut token_socket_map: HashMap<Token, TcpStream> = HashMap::new();

    loop 
    {    
        poll.poll(&mut events, Some(<Duration>::from_millis(50))).unwrap();

        for event in &events 
        {
            let token = event.token(); 
            match token  
            {
                TCP_SERVER_TOKEN => 
                {
                    loop 
                    {
                        match listener.accept() 
                        {
                            Ok((socket, _)) => {
                                counter += 1;
                                let new_token = Token(counter);
                                println!("{:?} New connection: {}  / counter : {}", chrono::offset::Local::now(), socket.peer_addr().unwrap(), counter);

                                // Register for readable events
                                poll.register(&socket, new_token, Ready::readable() | Ready::writable(), PollOpt::urgent()).unwrap();
                                token_socket_map.insert(new_token, socket);
                                break;
                            },
                            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock =>{ break /* No more connections ready to be accepted */ },
                            Err(e) => panic!("Unexpected error: {}", e),
                        }
                    }
                },
                SERIAL_TOKEN => 
                {
                    println!("SERIAL_TOKEN");
                    let ready = event.readiness();
                    if ready.is_readable() 
                    {
                        println!("serial is_readable");
                    }
                    if ready.is_writable() {
                        println!("serial is_writable");              
                    }
                },
                token if event.readiness().is_readable() => 
                {
                    //println!("tcp is_readable");
                },
                token if event.readiness().is_writable() => 
                {
                    //println!("tcp is_writable");
                },
                _ => (), // Ignore all other token
            }
        }
    }
}

Вывод:

SERIAL_TOKEN

серийный is_writable

2019-10-18T16: 37: 50.417091748 + 02: 00Новое соединение: 127.0.0.1:46606 / счетчик: 1

...