rust事件驱动的服务器最多可以处理多少个客户端?

时间:2019-07-12 11:58:02

标签: server rust

我正在Rust中使用事件驱动的服务器,并希望它能够将其连接到尽可能多的客户端。

但是我最多只能同时连接700个客户端并发送数据。如果我尝试增加客户端,则来自客户端的客户端连接开始断开。我正在使用线程创建多个客户端,它开始出现以下错误:

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value:
Os { code: 104, kind: ConnectionReset, message: "Connection reset by peer" }',
src/libcore/result.rs

如果禁用了数据发送,则它可以连接1017个客户端,并且可以通过允许进程打开大于1024个的文件来增加数据发送。

我检查了最高在我的操作系统中无法创建的线程数为62096。服务器程序的内存使用量也约为15KB。

我尝试将事件循环容量增加到20,480,尽管它不支持800个客户端。

Server.rs:

extern crate mio;
use mio::net::{TcpListener, TcpStream};
use mio::*;
use mio::{Poll, PollOpt, Ready, Token};
use std::collections::HashMap;
use std::env;
use std::io::{Error, Read, Write};

fn process_events(
    e: Event,
    listener: &TcpListener,
    poll: &Poll,
    clients: &mut HashMap<Token, TcpStream>,
    mut count: usize,
) {
    if e.token() == Token(0) {
        match listener.accept() {
            Ok((mut stream, addr)) => {
                let new_token = Token(count);
                println!("new token {:?}", new_token);

                poll.register(
                    &stream,
                    new_token,
                    Ready::readable(),
                    PollOpt::edge() | PollOpt::oneshot(),
                )
                .unwrap();

                println!("Got a client: {:?}", stream.peer_addr().unwrap());

                clients.insert(new_token, stream);
            }
            Err(e) => panic!("Error during connection{}", e),
        }
    }

    if e.token() != Token(0) && e.readiness().is_readable() {
        let mut buf = [0; 512];
        let mut t = e.token();
        let reader = clients.get_mut(&e.token()).unwrap().read(&mut buf);

        match reader {
            Ok(_) => {
                let bytes_no = reader.unwrap();
                println!("No of bytes read : {:?}, {:?}", bytes_no, e.token());
            }
            Err(e) => {
                println!("could not read: {}", e);
            }
        }

        poll.reregister(
            &clients[&e.token()],
            e.token(),
            Ready::readable(),
            PollOpt::edge() | PollOpt::oneshot(),
        )
        .unwrap();
    }
}

fn main() {
    const server: Token = Token(0);
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        eprintln!("Provide the argument");
        std::process::exit(1);
    }
    let listen = &args[1];
    let addr = listen.parse().unwrap();
    let mut listener = TcpListener::bind(&addr).expect("Could not bind");

    println!("Server listening on : {}", addr);

    let mut clients = HashMap::new();

    let mut eve = Events::with_capacity(20480);
    let poll = Poll::new().unwrap();

    let mut count = 1;

    poll.register(
        &listener,
        server,
        Ready::readable(),
        PollOpt::edge() | PollOpt::oneshot(),
    )
    .unwrap();

    loop {
        poll.poll(&mut eve, None);

        for e in &eve {
            process_events(e, &listener, &poll, &mut clients, count);
            if e.token() == Token(0) {
                count += 1;
            }
        }
        poll.reregister(
            &listener,
            server,
            Ready::readable(),
            PollOpt::edge() | PollOpt::oneshot(),
        )
        .unwrap();
    }
}

Client.rs:

use std::io;
use std::io::Write;
use std::net::TcpStream;
use std::thread;

fn handle_client() {
    let server_addr = String::from("localhost:3000");
    if let Ok(mut stream) = TcpStream::connect(server_addr) {
        println!("Connected to server {} ", c);
        let msg = [0u8; 512];
        loop {
            stream.write(&msg).unwrap();
        }
    } else {
        println!("could not connect");
    }
}
fn main() {
    for _i in 0..10000 {
        thread::spawn(move || handle_client());
    }
}

由于事件驱动的方法比多线程服务器更好,因此预期的客户端应该超过1020。

0 个答案:

没有答案