auto merge of #15265 : omasanori/rust/udp, r=alexcrichton

POSIX has recvfrom(2) and sendto(2), but their name seem not to be suitable with Rust. We already renamed getpeername(2) and getsockname(2), so I think it makes sense.

Alternatively, `receive_from` would be fine. However, we have `.recv()` so I chose `recv_from`.

What do you think? If this makes sense, should I provide `recvfrom` and `sendto` deprecated methods just calling new methods for compatibility?
This commit is contained in:
bors 2014-07-02 09:21:39 +00:00
commit 3fb3568377
5 changed files with 68 additions and 55 deletions

View File

@ -630,7 +630,7 @@ impl rtio::RtioSocket for UdpSocket {
#[cfg(unix)] type msglen_t = libc::size_t;
impl rtio::RtioUdpSocket for UdpSocket {
fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, rtio::SocketAddr)> {
fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(uint, rtio::SocketAddr)> {
let fd = self.fd();
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
@ -652,7 +652,7 @@ impl rtio::RtioUdpSocket for UdpSocket {
})
}
fn sendto(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> IoResult<()> {
fn send_to(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> IoResult<()> {
let (dst, dstlen) = addr_to_sockaddr(dst);
let dstp = &dst as *const _ as *const libc::sockaddr;
let dstlen = dstlen as libc::socklen_t;

View File

@ -269,8 +269,8 @@ pub trait RtioSocket {
}
pub trait RtioUdpSocket : RtioSocket {
fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
fn send_to(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()>;

View File

@ -197,13 +197,13 @@ mod test {
let listener = UdpWatcher::bind(local_loop(), addr2);
tx.send((listener.unwrap(), addr1));
let mut listener = UdpWatcher::bind(local_loop(), addr1).unwrap();
listener.sendto([1, 2, 3, 4], addr2).ok().unwrap();
listener.send_to([1, 2, 3, 4], addr2).ok().unwrap();
});
let task = pool.task(TaskOpts::new(), proc() {
let (mut watcher, addr) = rx.recv();
let mut buf = [0, ..10];
assert!(watcher.recvfrom(buf).ok().unwrap() == (4, addr));
assert!(watcher.recv_from(buf).ok().unwrap() == (4, addr));
});
pool.spawn_sched().send(sched::TaskFromFriend(task));

View File

@ -540,7 +540,7 @@ impl rtio::RtioSocket for UdpWatcher {
}
impl rtio::RtioUdpSocket for UdpWatcher {
fn recvfrom(&mut self, buf: &mut [u8])
fn recv_from(&mut self, buf: &mut [u8])
-> Result<(uint, rtio::SocketAddr), IoError>
{
let loop_ = self.uv_loop();
@ -607,7 +607,7 @@ impl rtio::RtioUdpSocket for UdpWatcher {
}
}
fn sendto(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> Result<(), IoError> {
fn send_to(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> Result<(), IoError> {
let m = self.fire_homing_missile();
let loop_ = self.uv_loop();
let guard = try!(self.write_access.grant(m));
@ -960,7 +960,7 @@ mod test {
Ok(mut w) => {
tx.send(());
let mut buf = [0u8, ..10];
match w.recvfrom(buf) {
match w.recv_from(buf) {
Ok((10, addr)) => assert!(addr == client),
e => fail!("{:?}", e),
}
@ -976,7 +976,7 @@ mod test {
let mut w = match UdpWatcher::bind(local_loop(), client) {
Ok(w) => w, Err(e) => fail!("{:?}", e)
};
match w.sendto([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], server) {
match w.send_to([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], server) {
Ok(()) => {}, Err(e) => fail!("{:?}", e)
}
}
@ -992,7 +992,7 @@ mod test {
Ok(mut w) => {
tx.send(());
let mut buf = [0u8, ..10];
match w.recvfrom(buf) {
match w.recv_from(buf) {
Ok((10, addr)) => assert!(addr == client),
e => fail!("{:?}", e),
}
@ -1008,7 +1008,7 @@ mod test {
let mut w = match UdpWatcher::bind(local_loop(), client) {
Ok(w) => w, Err(e) => fail!("{:?}", e)
};
match w.sendto([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], server) {
match w.send_to([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], server) {
Ok(()) => {}, Err(e) => fail!("{:?}", e)
}
}
@ -1057,16 +1057,16 @@ mod test {
spawn(proc() {
let mut client = UdpWatcher::bind(local_loop(), client_addr).unwrap();
rx.recv();
assert!(client.sendto([1], server_addr).is_ok());
assert!(client.sendto([2], server_addr).is_ok());
assert!(client.send_to([1], server_addr).is_ok());
assert!(client.send_to([2], server_addr).is_ok());
});
let mut server = UdpWatcher::bind(local_loop(), server_addr).unwrap();
tx.send(());
let mut buf1 = [0];
let mut buf2 = [0];
let (nread1, src1) = server.recvfrom(buf1).ok().unwrap();
let (nread2, src2) = server.recvfrom(buf2).ok().unwrap();
let (nread1, src1) = server.recv_from(buf1).ok().unwrap();
let (nread2, src2) = server.recv_from(buf2).ok().unwrap();
assert_eq!(nread1, 1);
assert_eq!(nread2, 1);
assert!(src1 == client_addr);
@ -1098,10 +1098,10 @@ mod test {
let mut buf = [1];
while buf[0] == 1 {
// send more data
assert!(server_out.sendto(msg, client_in_addr).is_ok());
assert!(server_out.send_to(msg, client_in_addr).is_ok());
total_bytes_sent += msg.len();
// check if the client has received enough
let res = server_in.recvfrom(buf);
let res = server_in.recv_from(buf);
assert!(res.is_ok());
let (nread, src) = res.ok().unwrap();
assert_eq!(nread, 1);
@ -1120,9 +1120,9 @@ mod test {
let mut buf = [0, .. 2048];
while total_bytes_recv < MAX {
// ask for more
assert!(client_out.sendto([1], server_in_addr).is_ok());
assert!(client_out.send_to([1], server_in_addr).is_ok());
// wait for data
let res = client_in.recvfrom(buf);
let res = client_in.recv_from(buf);
assert!(res.is_ok());
let (nread, src) = res.ok().unwrap();
assert!(src == server_out_addr);
@ -1132,7 +1132,7 @@ mod test {
}
}
// tell the server we're done
assert!(client_out.sendto([0], server_in_addr).is_ok());
assert!(client_out.send_to([0], server_in_addr).is_ok());
}
#[test]

View File

@ -45,12 +45,12 @@ use rt::rtio;
/// };
///
/// let mut buf = [0, ..10];
/// match socket.recvfrom(buf) {
/// match socket.recv_from(buf) {
/// Ok((amt, src)) => {
/// // Send a reply to the socket we received data from
/// let buf = buf.mut_slice_to(amt);
/// buf.reverse();
/// socket.sendto(buf, src);
/// socket.send_to(buf, src);
/// }
/// Err(e) => println!("couldn't receive a datagram: {}", e)
/// }
@ -72,9 +72,9 @@ impl UdpSocket {
/// Receives data from the socket. On success, returns the number of bytes
/// read and the address from whence the data came.
pub fn recvfrom(&mut self, buf: &mut [u8])
pub fn recv_from(&mut self, buf: &mut [u8])
-> IoResult<(uint, SocketAddr)> {
match self.obj.recvfrom(buf) {
match self.obj.recv_from(buf) {
Ok((amt, rtio::SocketAddr { ip, port })) => {
Ok((amt, SocketAddr { ip: super::from_rtio(ip), port: port }))
}
@ -82,15 +82,28 @@ impl UdpSocket {
}
}
#[allow(missing_doc)]
#[deprecated = "renamed to `recv_from`"]
pub fn recvfrom(&mut self, buf: &mut [u8])
-> IoResult<(uint, SocketAddr)> {
self.recv_from(buf)
}
/// Sends data on the socket to the given address. Returns nothing on
/// success.
pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
self.obj.sendto(buf, rtio::SocketAddr {
pub fn send_to(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
self.obj.send_to(buf, rtio::SocketAddr {
ip: super::to_rtio(dst.ip),
port: dst.port,
}).map_err(IoError::from_rtio_error)
}
#[allow(missing_doc)]
#[deprecated = "renamed to `send_to`"]
pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
self.send_to(buf, dst)
}
/// Creates a `UdpStream`, which allows use of the `Reader` and `Writer`
/// traits to receive and send data from the same address. This transfers
/// ownership of the socket to the stream.
@ -225,7 +238,7 @@ impl Reader for UdpStream {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
let peer = self.connected_to;
self.as_socket(|sock| {
match sock.recvfrom(buf) {
match sock.recv_from(buf) {
Ok((_nread, src)) if src != peer => Ok(0),
Ok((nread, _src)) => Ok(nread),
Err(e) => Err(e),
@ -237,7 +250,7 @@ impl Reader for UdpStream {
impl Writer for UdpStream {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
let connected_to = self.connected_to;
self.as_socket(|sock| sock.sendto(buf, connected_to))
self.as_socket(|sock| sock.send_to(buf, connected_to))
}
}
@ -266,7 +279,7 @@ mod test {
match UdpSocket::bind(client_ip) {
Ok(ref mut client) => {
rx1.recv();
client.sendto([99], server_ip).unwrap()
client.send_to([99], server_ip).unwrap()
}
Err(..) => fail!()
}
@ -277,7 +290,7 @@ mod test {
Ok(ref mut server) => {
tx1.send(());
let mut buf = [0];
match server.recvfrom(buf) {
match server.recv_from(buf) {
Ok((nread, src)) => {
assert_eq!(nread, 1);
assert_eq!(buf[0], 99);
@ -300,7 +313,7 @@ mod test {
match UdpSocket::bind(client_ip) {
Ok(ref mut client) => {
rx.recv();
client.sendto([99], server_ip).unwrap()
client.send_to([99], server_ip).unwrap()
}
Err(..) => fail!()
}
@ -310,7 +323,7 @@ mod test {
Ok(ref mut server) => {
tx.send(());
let mut buf = [0];
match server.recvfrom(buf) {
match server.recv_from(buf) {
Ok((nread, src)) => {
assert_eq!(nread, 1);
assert_eq!(buf[0], 99);
@ -429,9 +442,9 @@ mod test {
spawn(proc() {
let mut sock2 = sock2;
let mut buf = [0, 0];
assert_eq!(sock2.recvfrom(buf), Ok((1, addr1)));
assert_eq!(sock2.recv_from(buf), Ok((1, addr1)));
assert_eq!(buf[0], 1);
sock2.sendto([2], addr1).unwrap();
sock2.send_to([2], addr1).unwrap();
});
let sock3 = sock1.clone();
@ -441,12 +454,12 @@ mod test {
spawn(proc() {
let mut sock3 = sock3;
rx1.recv();
sock3.sendto([1], addr2).unwrap();
sock3.send_to([1], addr2).unwrap();
tx2.send(());
});
tx1.send(());
let mut buf = [0, 0];
assert_eq!(sock1.recvfrom(buf), Ok((1, addr2)));
assert_eq!(sock1.recv_from(buf), Ok((1, addr2)));
rx2.recv();
})
@ -460,9 +473,9 @@ mod test {
spawn(proc() {
let mut sock2 = sock2;
sock2.sendto([1], addr1).unwrap();
sock2.send_to([1], addr1).unwrap();
rx.recv();
sock2.sendto([2], addr1).unwrap();
sock2.send_to([2], addr1).unwrap();
rx.recv();
});
@ -472,12 +485,12 @@ mod test {
spawn(proc() {
let mut sock3 = sock3;
let mut buf = [0, 0];
sock3.recvfrom(buf).unwrap();
sock3.recv_from(buf).unwrap();
tx2.send(());
done.send(());
});
let mut buf = [0, 0];
sock1.recvfrom(buf).unwrap();
sock1.recv_from(buf).unwrap();
tx1.send(());
rx.recv();
@ -497,7 +510,7 @@ mod test {
let mut buf = [0, 1];
rx.recv();
match sock2.recvfrom(buf) {
match sock2.recv_from(buf) {
Ok(..) => {}
Err(e) => fail!("failed receive: {}", e),
}
@ -510,13 +523,13 @@ mod test {
let tx2 = tx.clone();
spawn(proc() {
let mut sock3 = sock3;
match sock3.sendto([1], addr2) {
match sock3.send_to([1], addr2) {
Ok(..) => { let _ = tx2.send_opt(()); }
Err(..) => {}
}
done.send(());
});
match sock1.sendto([2], addr2) {
match sock1.send_to([2], addr2) {
Ok(..) => { let _ = tx.send_opt(()); }
Err(..) => {}
}
@ -526,7 +539,7 @@ mod test {
serv_rx.recv();
})
iotest!(fn recvfrom_timeout() {
iotest!(fn recv_from_timeout() {
let addr1 = next_test_ip4();
let addr2 = next_test_ip4();
let mut a = UdpSocket::bind(addr1).unwrap();
@ -535,34 +548,34 @@ mod test {
let (tx2, rx2) = channel();
spawn(proc() {
let mut a = UdpSocket::bind(addr2).unwrap();
assert_eq!(a.recvfrom([0]), Ok((1, addr1)));
assert_eq!(a.sendto([0], addr1), Ok(()));
assert_eq!(a.recv_from([0]), Ok((1, addr1)));
assert_eq!(a.send_to([0], addr1), Ok(()));
rx.recv();
assert_eq!(a.sendto([0], addr1), Ok(()));
assert_eq!(a.send_to([0], addr1), Ok(()));
tx2.send(());
});
// Make sure that reads time out, but writes can continue
a.set_read_timeout(Some(20));
assert_eq!(a.recvfrom([0]).err().unwrap().kind, TimedOut);
assert_eq!(a.recvfrom([0]).err().unwrap().kind, TimedOut);
assert_eq!(a.sendto([0], addr2), Ok(()));
assert_eq!(a.recv_from([0]).err().unwrap().kind, TimedOut);
assert_eq!(a.recv_from([0]).err().unwrap().kind, TimedOut);
assert_eq!(a.send_to([0], addr2), Ok(()));
// Cloned handles should be able to block
let mut a2 = a.clone();
assert_eq!(a2.recvfrom([0]), Ok((1, addr2)));
assert_eq!(a2.recv_from([0]), Ok((1, addr2)));
// Clearing the timeout should allow for receiving
a.set_timeout(None);
tx.send(());
assert_eq!(a2.recvfrom([0]), Ok((1, addr2)));
assert_eq!(a2.recv_from([0]), Ok((1, addr2)));
// Make sure the child didn't die
rx2.recv();
})
iotest!(fn sendto_timeout() {
iotest!(fn send_to_timeout() {
let addr1 = next_test_ip4();
let addr2 = next_test_ip4();
let mut a = UdpSocket::bind(addr1).unwrap();
@ -570,7 +583,7 @@ mod test {
a.set_write_timeout(Some(1000));
for _ in range(0u, 100) {
match a.sendto([0, ..4*1024], addr2) {
match a.send_to([0, ..4*1024], addr2) {
Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
Err(IoError { kind: TimedOut, .. }) => break,
Err(e) => fail!("other error: {}", e),