2013-07-03 12 views
30

Sto cercando un esempio di server TCP in Rust.Esempio di server TCP scritto in Rust

O un "mondo Ciao" o un server di eco sarebbe fantastico.

+0

https://gist.github.com/thomaslee/4753338 – rags

+0

@rags: si dovrebbe fare una risposta di quel –

+0

@rags: in realtà, ho deciso di risolvere il problema per Rust 0.7 e postalo io stesso - sentiti libero di rispondere da solo se sei desideroso di farlo e io ne rimuoverò la copia. Il tuo Gist potrebbe fare anche con l'aggiornamento. –

risposta

38

Ecco un esempio molto semplice che utilizza std::net. È stato sviluppato contro l'attuale maestro di Rust e dovrebbe funzionare anche su 1. *.

Prestare attenzione a questo esempio; è semplificato; potresti non volere che vada nel panico se legare, ascoltare o accettare produce un errore.

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

fn main() { 
    let listener = TcpListener::bind("127.0.0.1:9123").unwrap(); 
    println!("listening started, ready to accept"); 
    for stream in listener.incoming() { 
     thread::spawn(|| { 
      let mut stream = stream.unwrap(); 
      stream.write(b"Hello World\r\n").unwrap(); 
     }); 
    } 
} 

Nota il paradigma per quanto riguarda l'accettazione; devi avviare tu stesso la richiesta accept() (in questo esempio utilizzeremo l'iteratore incoming() che chiama ogni volta accept()), e quindi ottieni il reale controllo reale di quali attività ci sono.

Di conseguenza, ho inserito il codice di gestione del flusso in un thread separato, ma non è necessario per richieste molto brevi (significa solo che non sarebbe possibile gestire una seconda richiesta durante la gestione del primo); si potrebbe anche rimuovere il thread::spawn(|| { ... }) su queste due linee. L'uso di thread aggiuntivi fornisce anche un certo grado di isolamento; se il thread si svolge, il server nel suo complesso non morirà (tenete presente, tuttavia, che l'esaurimento della memoria o il panico del distruttore durante lo svolgimento causeranno la morte dell'intero server).

+1

Questo codice non si compila più, puoi aggiornarlo? (Vorrei ma non sono sicuro di come generare l'attività) –

+3

@JeroenBollen: aggiornato. –

+0

Ancora non si compila più sul master. Ho capito fino a che TcpListener è passato a std :: net, ma sembra che il processo di spawning e scrittura in streaming sia cambiato pure – wump

4

semplici TCP eco-server di https://gist.github.com/seriyps/fd6d29442e16c44ba400

#![feature(phase)] 
#[phase(plugin, link)] extern crate log; 
extern crate green; 
extern crate rustuv; 

use std::io; 
use std::os; 
use std::io::{Listener,Acceptor,TcpStream}; 

// This is for green threads. If removed, will spawn 1 OS thread per client. 
#[start] 
fn start(argc: int, argv: *const *const u8) -> int { 
    green::start(argc, argv, rustuv::event_loop, main) 
} 


fn main() { 
    let host = "127.0.0.1"; 
    let port = 8080; 

    let sock = io::TcpListener::bind(host, port).unwrap(); 
    let mut acceptor = sock.listen(); 
    for stream in acceptor.incoming() { 
     match stream { 
      Err(e) => warn!("Accept err {}", e), 
      Ok(stream) => { 
       spawn(proc() { 
        debug!("{}", handle_client(stream)); 
       }) 
      } 
     } 
    } 
} 

fn handle_client(mut stream: io::TcpStream) -> io::IoResult<()> { 
    info!("New client {}", stream.peer_name()); 
    let mut buf = [0u8, ..4096]; 
    loop { 
     let got = try!(stream.read(buf)); 
     if got == 0 { 
      // Is it possible? Or IoError will be raised anyway? 
      break 
     } 
     try!(stream.write(buf.slice(0, got))); 
    } 
    Ok(()) 
} 
+0

Questo non funziona più - vedi il mio commento [qui] (https://gist.github.com/seriyps/fd6d29442e16c44ba400#gistcomment-1562789) per il perché. – ferrouswheel