Easier interface for TCP ::connect and ::bind.
Prior to this commit, TcpStream::connect and TcpListener::bind took a single SocketAddr argument. This worked well enough, but the API felt a little too "low level" for most simple use cases. A great example is connecting to rust-lang.org on port 80. Rust users would need to: 1. resolve the IP address of rust-lang.org using io::net::addrinfo::get_host_addresses. 2. check for errors 3. if all went well, use the returned IP address and the port number to construct a SocketAddr 4. pass this SocketAddr to TcpStream::connect. I'm modifying the type signature of TcpStream::connect and TcpListener::bind so that the API is a little easier to use. TcpStream::connect now accepts two arguments: a string describing the host/IP of the host we wish to connect to, and a u16 representing the remote port number. Similarly, TcpListener::bind has been modified to take two arguments: a string describing the local interface address (e.g. "0.0.0.0" or "127.0.0.1") and a u16 port number. Here's how to port your Rust code to use the new TcpStream::connect API: // old ::connect API let addr = SocketAddr{ip: Ipv4Addr{127, 0, 0, 1}, port: 8080}; let stream = TcpStream::connect(addr).unwrap() // new ::connect API (minimal change) let addr = SocketAddr{ip: Ipv4Addr{127, 0, 0, 1}, port: 8080}; let stream = TcpStream::connect(addr.ip.to_str(), addr.port()).unwrap() // new ::connect API (more compact) let stream = TcpStream::connect("127.0.0.1", 8080).unwrap() // new ::connect API (hostname) let stream = TcpStream::connect("rust-lang.org", 80) Similarly, for TcpListener::bind: // old ::bind API let addr = SocketAddr{ip: Ipv4Addr{0, 0, 0, 0}, port: 8080}; let mut acceptor = TcpListener::bind(addr).listen(); // new ::bind API (minimal change) let addr = SocketAddr{ip: Ipv4Addr{0, 0, 0, 0}, port: 8080}; let mut acceptor = TcpListener::bind(addr.ip.to_str(), addr.port()).listen() // new ::bind API (more compact) let mut acceptor = TcpListener::bind("0.0.0.0", 8080).listen() [breaking-change]
This commit is contained in:
parent
07d63228ea
commit
a57889a580
@ -19,7 +19,6 @@ use util;
|
||||
|
||||
use std::io::File;
|
||||
use std::io::fs;
|
||||
use std::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
use std::io::net::tcp;
|
||||
use std::io::process::ProcessExit;
|
||||
use std::io::process;
|
||||
@ -316,10 +315,7 @@ fn run_debuginfo_gdb_test(config: &config, props: &TestProps, testfile: &Path) {
|
||||
//waiting 1 second for gdbserver start
|
||||
timer::sleep(1000);
|
||||
let result = task::try(proc() {
|
||||
tcp::TcpStream::connect(SocketAddr {
|
||||
ip: Ipv4Addr(127, 0, 0, 1),
|
||||
port: 5039,
|
||||
}).unwrap();
|
||||
tcp::TcpStream::connect("127.0.0.1", 5039).unwrap();
|
||||
});
|
||||
if result.is_err() {
|
||||
continue;
|
||||
|
@ -83,11 +83,9 @@ Some examples of obvious things you might want to do
|
||||
|
||||
```rust,should_fail
|
||||
# #![allow(unused_must_use)]
|
||||
use std::io::net::ip::SocketAddr;
|
||||
use std::io::net::tcp::TcpStream;
|
||||
|
||||
let addr = from_str::<SocketAddr>("127.0.0.1:8080").unwrap();
|
||||
let mut socket = TcpStream::connect(addr).unwrap();
|
||||
let mut socket = TcpStream::connect("127.0.0.1", 8080).unwrap();
|
||||
socket.write(bytes!("GET / HTTP/1.0\n\n"));
|
||||
let response = socket.read_to_end();
|
||||
```
|
||||
@ -99,11 +97,9 @@ Some examples of obvious things you might want to do
|
||||
# fn foo() {
|
||||
# #![allow(dead_code)]
|
||||
use std::io::{TcpListener, TcpStream};
|
||||
use std::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
use std::io::{Acceptor, Listener};
|
||||
|
||||
let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 80 };
|
||||
let listener = TcpListener::bind(addr);
|
||||
let listener = TcpListener::bind("127.0.0.1", 80);
|
||||
|
||||
// bind the listener to the specified address
|
||||
let mut acceptor = listener.listen();
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -19,8 +19,14 @@
|
||||
|
||||
use clone::Clone;
|
||||
use io::IoResult;
|
||||
use iter::Iterator;
|
||||
use slice::ImmutableVector;
|
||||
use result::{Ok,Err};
|
||||
use io::net::addrinfo::get_host_addresses;
|
||||
use io::net::ip::SocketAddr;
|
||||
use io::{IoError, ConnectionFailed, InvalidInput};
|
||||
use io::{Reader, Writer, Listener, Acceptor};
|
||||
use from_str::FromStr;
|
||||
use kinds::Send;
|
||||
use option::{None, Some, Option};
|
||||
use owned::Box;
|
||||
@ -35,10 +41,8 @@ use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
|
||||
/// ```no_run
|
||||
/// # #![allow(unused_must_use)]
|
||||
/// use std::io::net::tcp::TcpStream;
|
||||
/// use std::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
///
|
||||
/// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 };
|
||||
/// let mut stream = TcpStream::connect(addr);
|
||||
/// let mut stream = TcpStream::connect("127.0.0.1", 34254);
|
||||
///
|
||||
/// stream.write([1]);
|
||||
/// let mut buf = [0];
|
||||
@ -54,13 +58,32 @@ impl TcpStream {
|
||||
TcpStream { obj: s }
|
||||
}
|
||||
|
||||
/// Creates a TCP connection to a remote socket address.
|
||||
/// Open a TCP connection to a remote host by hostname or IP address.
|
||||
///
|
||||
/// If no error is encountered, then `Ok(stream)` is returned.
|
||||
pub fn connect(addr: SocketAddr) -> IoResult<TcpStream> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.tcp_connect(addr, None).map(TcpStream::new)
|
||||
})
|
||||
/// `host` can be a hostname or IP address string. If no error is
|
||||
/// encountered, then `Ok(stream)` is returned.
|
||||
pub fn connect(host: &str, port: u16) -> IoResult<TcpStream> {
|
||||
let addresses = try!(get_host_addresses(host));
|
||||
let mut err = IoError{
|
||||
kind: ConnectionFailed,
|
||||
desc: "no addresses found for hostname",
|
||||
detail: None
|
||||
};
|
||||
for address in addresses.iter() {
|
||||
let socket_addr = SocketAddr{ip: *address, port: port};
|
||||
let result = LocalIo::maybe_raise(|io| {
|
||||
io.tcp_connect(socket_addr, None).map(TcpStream::new)
|
||||
});
|
||||
match result {
|
||||
Ok(stream) => {
|
||||
return Ok(stream)
|
||||
}
|
||||
Err(connect_err) => {
|
||||
err = connect_err
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
|
||||
/// Creates a TCP connection to a remote socket address, timing out after
|
||||
@ -121,10 +144,8 @@ impl TcpStream {
|
||||
/// # #![allow(unused_must_use)]
|
||||
/// use std::io::timer;
|
||||
/// use std::io::net::tcp::TcpStream;
|
||||
/// use std::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
///
|
||||
/// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 };
|
||||
/// let mut stream = TcpStream::connect(addr).unwrap();
|
||||
/// let mut stream = TcpStream::connect("127.0.0.1", 34254).unwrap();
|
||||
/// let stream2 = stream.clone();
|
||||
///
|
||||
/// spawn(proc() {
|
||||
@ -251,11 +272,9 @@ impl Writer for TcpStream {
|
||||
/// # fn foo() {
|
||||
/// # #![allow(dead_code)]
|
||||
/// use std::io::{TcpListener, TcpStream};
|
||||
/// use std::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
/// use std::io::{Acceptor, Listener};
|
||||
///
|
||||
/// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 80 };
|
||||
/// let listener = TcpListener::bind(addr);
|
||||
/// let listener = TcpListener::bind("127.0.0.1", 80);
|
||||
///
|
||||
/// // bind the listener to the specified address
|
||||
/// let mut acceptor = listener.listen();
|
||||
@ -284,17 +303,29 @@ pub struct TcpListener {
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
/// Creates a new `TcpListener` which will be bound to the specified local
|
||||
/// socket address. This listener is not ready for accepting connections,
|
||||
/// Creates a new `TcpListener` which will be bound to the specified IP
|
||||
/// and port. This listener is not ready for accepting connections,
|
||||
/// `listen` must be called on it before that's possible.
|
||||
///
|
||||
/// Binding with a port number of 0 will request that the OS assigns a port
|
||||
/// to this listener. The port allocated can be queried via the
|
||||
/// `socket_name` function.
|
||||
pub fn bind(addr: SocketAddr) -> IoResult<TcpListener> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.tcp_bind(addr).map(|l| TcpListener { obj: l })
|
||||
})
|
||||
pub fn bind(addr: &str, port: u16) -> IoResult<TcpListener> {
|
||||
match FromStr::from_str(addr) {
|
||||
Some(ip) => {
|
||||
let socket_addr = SocketAddr{ip: ip, port: port};
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.tcp_bind(socket_addr).map(|l| TcpListener { obj: l })
|
||||
})
|
||||
}
|
||||
None => {
|
||||
Err(IoError{
|
||||
kind: InvalidInput,
|
||||
desc: "invalid IP address specified",
|
||||
detail: None
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the local socket address of this listener.
|
||||
@ -338,11 +369,9 @@ impl TcpAcceptor {
|
||||
/// ```no_run
|
||||
/// # #![allow(experimental)]
|
||||
/// use std::io::net::tcp::TcpListener;
|
||||
/// use std::io::net::ip::{SocketAddr, Ipv4Addr};
|
||||
/// use std::io::{Listener, Acceptor, TimedOut};
|
||||
///
|
||||
/// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8482 };
|
||||
/// let mut a = TcpListener::bind(addr).listen().unwrap();
|
||||
/// let mut a = TcpListener::bind("127.0.0.1", 8482).listen().unwrap();
|
||||
///
|
||||
/// // After 100ms have passed, all accepts will fail
|
||||
/// a.set_timeout(Some(100));
|
||||
@ -382,27 +411,96 @@ mod test {
|
||||
|
||||
// FIXME #11530 this fails on android because tests are run as root
|
||||
iotest!(fn bind_error() {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
match TcpListener::bind(addr) {
|
||||
match TcpListener::bind("0.0.0.0", 1) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, PermissionDenied),
|
||||
}
|
||||
} #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
|
||||
|
||||
iotest!(fn connect_error() {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
match TcpStream::connect(addr) {
|
||||
match TcpStream::connect("0.0.0.0", 1) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, ConnectionRefused),
|
||||
}
|
||||
})
|
||||
|
||||
iotest!(fn smoke_test_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
iotest!(fn listen_ip4_localhost() {
|
||||
let socket_addr = next_test_ip4();
|
||||
let ip_str = socket_addr.ip.to_str();
|
||||
let port = socket_addr.port;
|
||||
let listener = TcpListener::bind(ip_str, port);
|
||||
let mut acceptor = listener.listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect("localhost", port);
|
||||
stream.write([144]).unwrap();
|
||||
});
|
||||
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 144);
|
||||
})
|
||||
|
||||
iotest!(fn connect_localhost() {
|
||||
let addr = next_test_ip4();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut stream = TcpStream::connect("localhost", addr.port);
|
||||
stream.write([64]).unwrap();
|
||||
});
|
||||
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 64);
|
||||
})
|
||||
|
||||
iotest!(fn connect_ip4_loopback() {
|
||||
let addr = next_test_ip4();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut stream = TcpStream::connect("127.0.0.1", addr.port);
|
||||
stream.write([44]).unwrap();
|
||||
});
|
||||
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 44);
|
||||
})
|
||||
|
||||
iotest!(fn connect_ip6_loopback() {
|
||||
let addr = next_test_ip6();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut stream = TcpStream::connect("::1", addr.port);
|
||||
stream.write([66]).unwrap();
|
||||
});
|
||||
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 66);
|
||||
})
|
||||
|
||||
iotest!(fn smoke_test_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
stream.write([99]).unwrap();
|
||||
});
|
||||
|
||||
@ -414,10 +512,12 @@ mod test {
|
||||
|
||||
iotest!(fn smoke_test_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
stream.write([99]).unwrap();
|
||||
});
|
||||
|
||||
@ -429,10 +529,12 @@ mod test {
|
||||
|
||||
iotest!(fn read_eof_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
let _stream = TcpStream::connect(ip_str, port);
|
||||
// Close
|
||||
});
|
||||
|
||||
@ -444,10 +546,12 @@ mod test {
|
||||
|
||||
iotest!(fn read_eof_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
let _stream = TcpStream::connect(ip_str, port);
|
||||
// Close
|
||||
});
|
||||
|
||||
@ -459,10 +563,12 @@ mod test {
|
||||
|
||||
iotest!(fn read_eof_twice_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
let _stream = TcpStream::connect(ip_str, port);
|
||||
// Close
|
||||
});
|
||||
|
||||
@ -482,10 +588,12 @@ mod test {
|
||||
|
||||
iotest!(fn read_eof_twice_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
let _stream = TcpStream::connect(ip_str, port);
|
||||
// Close
|
||||
});
|
||||
|
||||
@ -505,10 +613,12 @@ mod test {
|
||||
|
||||
iotest!(fn write_close_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
let _stream = TcpStream::connect(ip_str, port);
|
||||
// Close
|
||||
});
|
||||
|
||||
@ -530,10 +640,12 @@ mod test {
|
||||
|
||||
iotest!(fn write_close_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
let _stream = TcpStream::connect(ip_str, port);
|
||||
// Close
|
||||
});
|
||||
|
||||
@ -555,12 +667,14 @@ mod test {
|
||||
|
||||
iotest!(fn multiple_connect_serial_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let max = 10u;
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
for _ in range(0, max) {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
stream.write([99]).unwrap();
|
||||
}
|
||||
});
|
||||
@ -574,12 +688,14 @@ mod test {
|
||||
|
||||
iotest!(fn multiple_connect_serial_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let max = 10u;
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
for _ in range(0, max) {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
stream.write([99]).unwrap();
|
||||
}
|
||||
});
|
||||
@ -593,8 +709,10 @@ mod test {
|
||||
|
||||
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip4() {
|
||||
let addr = next_test_ip4();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
static MAX: int = 10;
|
||||
let acceptor = TcpListener::bind(addr).listen();
|
||||
let acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut acceptor = acceptor;
|
||||
@ -613,11 +731,13 @@ mod test {
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
if i == MAX { return }
|
||||
|
||||
spawn(proc() {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
@ -628,8 +748,10 @@ mod test {
|
||||
|
||||
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip6() {
|
||||
let addr = next_test_ip6();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
static MAX: int = 10;
|
||||
let acceptor = TcpListener::bind(addr).listen();
|
||||
let acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut acceptor = acceptor;
|
||||
@ -648,11 +770,13 @@ mod test {
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
if i == MAX { return }
|
||||
|
||||
spawn(proc() {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
@ -664,7 +788,9 @@ mod test {
|
||||
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip4() {
|
||||
static MAX: int = 10;
|
||||
let addr = next_test_ip4();
|
||||
let acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut acceptor = acceptor;
|
||||
@ -683,11 +809,13 @@ mod test {
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
if i == MAX { return }
|
||||
|
||||
spawn(proc() {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
@ -699,7 +827,9 @@ mod test {
|
||||
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip6() {
|
||||
static MAX: int = 10;
|
||||
let addr = next_test_ip6();
|
||||
let acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut acceptor = acceptor;
|
||||
@ -718,11 +848,13 @@ mod test {
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
if i == MAX { return }
|
||||
|
||||
spawn(proc() {
|
||||
debug!("connecting");
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
let mut stream = TcpStream::connect(ip_str, port);
|
||||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
@ -732,7 +864,9 @@ mod test {
|
||||
})
|
||||
|
||||
pub fn socket_name(addr: SocketAddr) {
|
||||
let mut listener = TcpListener::bind(addr).unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut listener = TcpListener::bind(ip_str, port).unwrap();
|
||||
|
||||
// Make sure socket_name gives
|
||||
// us the socket we binded to.
|
||||
@ -742,13 +876,15 @@ mod test {
|
||||
}
|
||||
|
||||
pub fn peer_name(addr: SocketAddr) {
|
||||
let acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
spawn(proc() {
|
||||
let mut acceptor = acceptor;
|
||||
acceptor.accept().unwrap();
|
||||
});
|
||||
|
||||
let stream = TcpStream::connect(addr);
|
||||
let stream = TcpStream::connect(ip_str, port);
|
||||
|
||||
assert!(stream.is_ok());
|
||||
let mut stream = stream.unwrap();
|
||||
@ -774,9 +910,11 @@ mod test {
|
||||
|
||||
iotest!(fn partial_read() {
|
||||
let addr = next_test_ip4();
|
||||
let port = addr.port;
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
let mut srv = TcpListener::bind(addr).listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let mut srv = TcpListener::bind(ip_str, port).listen().unwrap();
|
||||
tx.send(());
|
||||
let mut cl = srv.accept().unwrap();
|
||||
cl.write([10]).unwrap();
|
||||
@ -786,7 +924,8 @@ mod test {
|
||||
});
|
||||
|
||||
rx.recv();
|
||||
let mut c = TcpStream::connect(addr).unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let mut c = TcpStream::connect(ip_str, port).unwrap();
|
||||
let mut b = [0, ..10];
|
||||
assert_eq!(c.read(b), Ok(1));
|
||||
c.write([1]).unwrap();
|
||||
@ -795,9 +934,11 @@ mod test {
|
||||
|
||||
iotest!(fn double_bind() {
|
||||
let addr = next_test_ip4();
|
||||
let listener = TcpListener::bind(addr).unwrap().listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let listener = TcpListener::bind(ip_str, port).unwrap().listen();
|
||||
assert!(listener.is_ok());
|
||||
match TcpListener::bind(addr).listen() {
|
||||
match TcpListener::bind(ip_str, port).listen() {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => {
|
||||
assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
|
||||
@ -807,17 +948,20 @@ mod test {
|
||||
|
||||
iotest!(fn fast_rebind() {
|
||||
let addr = next_test_ip4();
|
||||
let port = addr.port;
|
||||
let (tx, rx) = channel();
|
||||
|
||||
spawn(proc() {
|
||||
let ip_str = addr.ip.to_str();
|
||||
rx.recv();
|
||||
let _stream = TcpStream::connect(addr).unwrap();
|
||||
let _stream = TcpStream::connect(ip_str, port).unwrap();
|
||||
// Close
|
||||
rx.recv();
|
||||
});
|
||||
|
||||
{
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
tx.send(());
|
||||
{
|
||||
let _stream = acceptor.accept().unwrap();
|
||||
@ -826,15 +970,17 @@ mod test {
|
||||
}
|
||||
// Close listener
|
||||
}
|
||||
let _listener = TcpListener::bind(addr);
|
||||
let _listener = TcpListener::bind(addr.ip.to_str(), port);
|
||||
})
|
||||
|
||||
iotest!(fn tcp_clone_smoke() {
|
||||
let addr = next_test_ip4();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut s = TcpStream::connect(addr);
|
||||
let mut s = TcpStream::connect(ip_str, port);
|
||||
let mut buf = [0, 0];
|
||||
assert_eq!(s.read(buf), Ok(1));
|
||||
assert_eq!(buf[0], 1);
|
||||
@ -860,12 +1006,14 @@ mod test {
|
||||
|
||||
iotest!(fn tcp_clone_two_read() {
|
||||
let addr = next_test_ip6();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
let (tx1, rx) = channel();
|
||||
let tx2 = tx1.clone();
|
||||
|
||||
spawn(proc() {
|
||||
let mut s = TcpStream::connect(addr);
|
||||
let mut s = TcpStream::connect(ip_str, port);
|
||||
s.write([1]).unwrap();
|
||||
rx.recv();
|
||||
s.write([2]).unwrap();
|
||||
@ -892,10 +1040,12 @@ mod test {
|
||||
|
||||
iotest!(fn tcp_clone_two_write() {
|
||||
let addr = next_test_ip4();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut acceptor = TcpListener::bind(ip_str, port).listen();
|
||||
|
||||
spawn(proc() {
|
||||
let mut s = TcpStream::connect(addr);
|
||||
let mut s = TcpStream::connect(ip_str, port);
|
||||
let mut buf = [0, 1];
|
||||
s.read(buf).unwrap();
|
||||
s.read(buf).unwrap();
|
||||
@ -919,7 +1069,9 @@ mod test {
|
||||
use rt::rtio::RtioTcpStream;
|
||||
|
||||
let addr = next_test_ip4();
|
||||
let a = TcpListener::bind(addr).unwrap().listen();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let a = TcpListener::bind(ip_str, port).unwrap().listen();
|
||||
spawn(proc() {
|
||||
let mut a = a;
|
||||
let mut c = a.accept().unwrap();
|
||||
@ -927,7 +1079,7 @@ mod test {
|
||||
c.write([1]).unwrap();
|
||||
});
|
||||
|
||||
let mut s = TcpStream::connect(addr).unwrap();
|
||||
let mut s = TcpStream::connect(ip_str, port).unwrap();
|
||||
assert!(s.obj.close_write().is_ok());
|
||||
assert!(s.write([1]).is_err());
|
||||
assert_eq!(s.read_to_end(), Ok(vec!(1)));
|
||||
@ -935,7 +1087,9 @@ mod test {
|
||||
|
||||
iotest!(fn accept_timeout() {
|
||||
let addr = next_test_ip4();
|
||||
let mut a = TcpListener::bind(addr).unwrap().listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut a = TcpListener::bind(ip_str, port).unwrap().listen().unwrap();
|
||||
|
||||
a.set_timeout(Some(10));
|
||||
|
||||
@ -954,7 +1108,7 @@ mod test {
|
||||
if !cfg!(target_os = "freebsd") {
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
tx.send(TcpStream::connect(addr).unwrap());
|
||||
tx.send(TcpStream::connect(addr.ip.to_str(), port).unwrap());
|
||||
});
|
||||
let l = rx.recv();
|
||||
for i in range(0, 1001) {
|
||||
@ -971,14 +1125,16 @@ mod test {
|
||||
// Unset the timeout and make sure that this always blocks.
|
||||
a.set_timeout(None);
|
||||
spawn(proc() {
|
||||
drop(TcpStream::connect(addr).unwrap());
|
||||
drop(TcpStream::connect(addr.ip.to_str(), port).unwrap());
|
||||
});
|
||||
a.accept().unwrap();
|
||||
})
|
||||
|
||||
iotest!(fn close_readwrite_smoke() {
|
||||
let addr = next_test_ip4();
|
||||
let a = TcpListener::bind(addr).listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let a = TcpListener::bind(ip_str, port).listen().unwrap();
|
||||
let (_tx, rx) = channel::<()>();
|
||||
spawn(proc() {
|
||||
let mut a = a;
|
||||
@ -987,7 +1143,7 @@ mod test {
|
||||
});
|
||||
|
||||
let mut b = [0];
|
||||
let mut s = TcpStream::connect(addr).unwrap();
|
||||
let mut s = TcpStream::connect(ip_str, port).unwrap();
|
||||
let mut s2 = s.clone();
|
||||
|
||||
// closing should prevent reads/writes
|
||||
@ -1014,7 +1170,9 @@ mod test {
|
||||
|
||||
iotest!(fn close_read_wakes_up() {
|
||||
let addr = next_test_ip4();
|
||||
let a = TcpListener::bind(addr).listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let a = TcpListener::bind(ip_str, port).listen().unwrap();
|
||||
let (_tx, rx) = channel::<()>();
|
||||
spawn(proc() {
|
||||
let mut a = a;
|
||||
@ -1022,7 +1180,7 @@ mod test {
|
||||
let _ = rx.recv_opt();
|
||||
});
|
||||
|
||||
let mut s = TcpStream::connect(addr).unwrap();
|
||||
let mut s = TcpStream::connect(ip_str, port).unwrap();
|
||||
let s2 = s.clone();
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
@ -1039,10 +1197,12 @@ mod test {
|
||||
|
||||
iotest!(fn readwrite_timeouts() {
|
||||
let addr = next_test_ip6();
|
||||
let mut a = TcpListener::bind(addr).listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut a = TcpListener::bind(ip_str, port).listen().unwrap();
|
||||
let (tx, rx) = channel::<()>();
|
||||
spawn(proc() {
|
||||
let mut s = TcpStream::connect(addr).unwrap();
|
||||
let mut s = TcpStream::connect(ip_str, port).unwrap();
|
||||
rx.recv();
|
||||
assert!(s.write([0]).is_ok());
|
||||
let _ = rx.recv_opt();
|
||||
@ -1071,10 +1231,12 @@ mod test {
|
||||
|
||||
iotest!(fn read_timeouts() {
|
||||
let addr = next_test_ip6();
|
||||
let mut a = TcpListener::bind(addr).listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut a = TcpListener::bind(ip_str, port).listen().unwrap();
|
||||
let (tx, rx) = channel::<()>();
|
||||
spawn(proc() {
|
||||
let mut s = TcpStream::connect(addr).unwrap();
|
||||
let mut s = TcpStream::connect(ip_str, port).unwrap();
|
||||
rx.recv();
|
||||
let mut amt = 0;
|
||||
while amt < 100 * 128 * 1024 {
|
||||
@ -1099,10 +1261,12 @@ mod test {
|
||||
|
||||
iotest!(fn write_timeouts() {
|
||||
let addr = next_test_ip6();
|
||||
let mut a = TcpListener::bind(addr).listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut a = TcpListener::bind(ip_str, port).listen().unwrap();
|
||||
let (tx, rx) = channel::<()>();
|
||||
spawn(proc() {
|
||||
let mut s = TcpStream::connect(addr).unwrap();
|
||||
let mut s = TcpStream::connect(ip_str, port).unwrap();
|
||||
rx.recv();
|
||||
assert!(s.write([0]).is_ok());
|
||||
let _ = rx.recv_opt();
|
||||
@ -1126,10 +1290,12 @@ mod test {
|
||||
|
||||
iotest!(fn timeout_concurrent_read() {
|
||||
let addr = next_test_ip6();
|
||||
let mut a = TcpListener::bind(addr).listen().unwrap();
|
||||
let ip_str = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let mut a = TcpListener::bind(ip_str, port).listen().unwrap();
|
||||
let (tx, rx) = channel::<()>();
|
||||
spawn(proc() {
|
||||
let mut s = TcpStream::connect(addr).unwrap();
|
||||
let mut s = TcpStream::connect(ip_str, port).unwrap();
|
||||
rx.recv();
|
||||
assert_eq!(s.write([0]), Ok(()));
|
||||
let _ = rx.recv_opt();
|
||||
|
@ -54,6 +54,8 @@ macro_rules! iotest (
|
||||
iotest!(fn eventual_timeout() {
|
||||
use native;
|
||||
let addr = next_test_ip4();
|
||||
let host = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
|
||||
// Use a native task to receive connections because it turns out libuv is
|
||||
// really good at accepting connections and will likely run out of file
|
||||
@ -61,7 +63,7 @@ iotest!(fn eventual_timeout() {
|
||||
let (tx1, rx1) = channel();
|
||||
let (_tx2, rx2) = channel::<()>();
|
||||
native::task::spawn(proc() {
|
||||
let _l = TcpListener::bind(addr).unwrap().listen();
|
||||
let _l = TcpListener::bind(host, port).unwrap().listen();
|
||||
tx1.send(());
|
||||
let _ = rx2.recv_opt();
|
||||
});
|
||||
@ -80,7 +82,9 @@ iotest!(fn eventual_timeout() {
|
||||
|
||||
iotest!(fn timeout_success() {
|
||||
let addr = next_test_ip4();
|
||||
let _l = TcpListener::bind(addr).unwrap().listen();
|
||||
let host = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
let _l = TcpListener::bind(host, port).unwrap().listen();
|
||||
|
||||
assert!(TcpStream::connect_timeout(addr, 1000).is_ok());
|
||||
})
|
||||
|
@ -19,7 +19,6 @@ extern crate libc;
|
||||
extern crate green;
|
||||
extern crate rustuv;
|
||||
|
||||
use std::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
use std::io::net::tcp::{TcpListener, TcpStream};
|
||||
use std::io::{Acceptor, Listener};
|
||||
use std::task::TaskBuilder;
|
||||
@ -38,10 +37,11 @@ fn main() {
|
||||
unsafe { libc::exit(1) }
|
||||
});
|
||||
|
||||
let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 0 };
|
||||
let host = "127.0.0.1";
|
||||
let port = 0;
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
let mut listener = TcpListener::bind(addr).unwrap();
|
||||
let mut listener = TcpListener::bind(host, port).unwrap();
|
||||
tx.send(listener.socket_name().unwrap());
|
||||
let mut acceptor = listener.listen();
|
||||
loop {
|
||||
@ -57,6 +57,8 @@ fn main() {
|
||||
}
|
||||
});
|
||||
let addr = rx.recv();
|
||||
let host = addr.ip.to_str();
|
||||
let port = addr.port;
|
||||
|
||||
let (tx, rx) = channel();
|
||||
for _ in range(0, 1000) {
|
||||
@ -64,7 +66,7 @@ fn main() {
|
||||
let mut builder = TaskBuilder::new();
|
||||
builder.opts.stack_size = Some(32 * 1024);
|
||||
builder.spawn(proc() {
|
||||
match TcpStream::connect(addr) {
|
||||
match TcpStream::connect(host, port) {
|
||||
Ok(stream) => {
|
||||
let mut stream = stream;
|
||||
stream.write([1]);
|
||||
|
Loading…
Reference in New Issue
Block a user