2015-02-03 4 views
0

Я пытаюсь получить вход пользователя от stdin, получая данные из сокета. Затем я хочу отправить пользовательский ввод в сокет. Как я могу передать сокет потоку, который может отправлять и читать, а чтение основной функции из stdin и отправка его в сокет. Эта функция не должна считываться из сокета. Я бы предпочел, чтобы использовать BufferedStream в качестве устройства для чтения сокетов.
Тема принимает и отправляет - (while) - функция получает вход от stdin и отправляет в сокет.Как «разделить» сокет между потоком и функцией?

+0

Зачем вам нужно разделять сокет между потоками? Не могли бы вы просто убрать строки чтения между потоками? – Shepmaster

+0

@Shepmaster \t \t В действительности я просто пытаюсь разделить сокет между потоком и функцией. Могу ли я просто поделиться собственностью сокета с помощью Arc? – user3746744

+0

У меня есть рабочий пример. Я просто создал поток для каждой функции и передал сокеты. Кажется, работает достаточно хорошо. :) – user3746744

ответ

2

Это зависит от того, что вы на самом деле делаете с сокетом и стандартным входом, и как вы чередовали их.

Чистейший способ заключается в использовании каналов для передачи данных между потоками:

use std::old_io as io; 
use std::old_io::net::tcp::TcpStream; 
use std::sync::mpsc::channel; 
use std::thread::Thread; 

fn main() { 
    let (tx, rx) = channel::<Vec<u8>>(); 
    let g = Thread::scoped(move || { 
     let mut s = TcpStream::connect("example.com:80").unwrap(); 
     println!("> Opened connection, waiting for input"); 
     let query = rx.recv().unwrap(); 
     s.write(&query).unwrap(); 
     s.close_write(); 

     let r = String::from_utf8(s.read_to_end().unwrap()).unwrap(); 
     println!("Response:\n{}", r); 
    }); 

    let mut data = Vec::new(); 
    for line in io::stdin().lock().lines() { 
     let line = line.unwrap(); 
     if line.trim().is_empty() { break; } 
     data.push_all(line.trim().as_bytes()); 
     data.push_all(b"\r\n"); 
    } 
    data.push_all(b"\r\n"); 
    tx.send(data).unwrap(); 

    println!("Waiting for response..."); 
} 

Существует clone() метод на TcpStream которые «расколов» гнездо на две части. Вы можете передать их в разные темы. Однако рассмотрим использование каналов.