@@ -83,6 +83,30 @@ impl UdpSocket {
8383 self . 0 . recv_from ( buf)
8484 }
8585
86+ /// Receives data from the socket, without removing it from the queue.
87+ ///
88+ /// Successive calls return the same data. This is accomplished by passing
89+ /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
90+ ///
91+ /// On success, returns the number of bytes peeked and the address from
92+ /// whence the data came.
93+ ///
94+ /// # Examples
95+ ///
96+ /// ```no_run
97+ /// #![feature(peek)]
98+ /// use std::net::UdpSocket;
99+ ///
100+ /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
101+ /// let mut buf = [0; 10];
102+ /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
103+ /// .expect("Didn't receive data");
104+ /// ```
105+ #[ unstable( feature = "peek" , issue = "38980" ) ]
106+ pub fn peek_from ( & self , buf : & mut [ u8 ] ) -> io:: Result < ( usize , SocketAddr ) > {
107+ self . 0 . peek_from ( buf)
108+ }
109+
86110 /// Sends data on the socket to the given address. On success, returns the
87111 /// number of bytes written.
88112 ///
@@ -579,6 +603,37 @@ impl UdpSocket {
579603 self . 0 . recv ( buf)
580604 }
581605
606+ /// Receives data on the socket from the remote adress to which it is
607+ /// connected, without removing that data from the queue. On success,
608+ /// returns the number of bytes peeked.
609+ ///
610+ /// Successive calls return the same data. This is accomplished by passing
611+ /// `MSG_PEEK` as a flag to the underlying `recv` system call.
612+ ///
613+ /// # Errors
614+ ///
615+ /// This method will fail if the socket is not connected. The `connect` method
616+ /// will connect this socket to a remote address.
617+ ///
618+ /// # Examples
619+ ///
620+ /// ```no_run
621+ /// #![feature(peek)]
622+ /// use std::net::UdpSocket;
623+ ///
624+ /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
625+ /// socket.connect("127.0.0.1:8080").expect("connect function failed");
626+ /// let mut buf = [0; 10];
627+ /// match socket.peek(&mut buf) {
628+ /// Ok(received) => println!("received {} bytes", received),
629+ /// Err(e) => println!("peek function failed: {:?}", e),
630+ /// }
631+ /// ```
632+ #[ unstable( feature = "peek" , issue = "38980" ) ]
633+ pub fn peek ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
634+ self . 0 . peek ( buf)
635+ }
636+
582637 /// Moves this UDP socket into or out of nonblocking mode.
583638 ///
584639 /// On Unix this corresponds to calling fcntl, and on Windows this
@@ -869,6 +924,48 @@ mod tests {
869924 assert_eq ! ( b"hello world" , & buf[ ..] ) ;
870925 }
871926
927+ #[ test]
928+ fn connect_send_peek_recv ( ) {
929+ each_ip ( & mut |addr, _| {
930+ let socket = t ! ( UdpSocket :: bind( & addr) ) ;
931+ t ! ( socket. connect( addr) ) ;
932+
933+ t ! ( socket. send( b"hello world" ) ) ;
934+
935+ for _ in 1 ..3 {
936+ let mut buf = [ 0 ; 11 ] ;
937+ let size = t ! ( socket. peek( & mut buf) ) ;
938+ assert_eq ! ( b"hello world" , & buf[ ..] ) ;
939+ assert_eq ! ( size, 11 ) ;
940+ }
941+
942+ let mut buf = [ 0 ; 11 ] ;
943+ let size = t ! ( socket. recv( & mut buf) ) ;
944+ assert_eq ! ( b"hello world" , & buf[ ..] ) ;
945+ assert_eq ! ( size, 11 ) ;
946+ } )
947+ }
948+
949+ #[ test]
950+ fn peek_from ( ) {
951+ each_ip ( & mut |addr, _| {
952+ let socket = t ! ( UdpSocket :: bind( & addr) ) ;
953+ t ! ( socket. send_to( b"hello world" , & addr) ) ;
954+
955+ for _ in 1 ..3 {
956+ let mut buf = [ 0 ; 11 ] ;
957+ let ( size, _) = t ! ( socket. peek_from( & mut buf) ) ;
958+ assert_eq ! ( b"hello world" , & buf[ ..] ) ;
959+ assert_eq ! ( size, 11 ) ;
960+ }
961+
962+ let mut buf = [ 0 ; 11 ] ;
963+ let ( size, _) = t ! ( socket. recv_from( & mut buf) ) ;
964+ assert_eq ! ( b"hello world" , & buf[ ..] ) ;
965+ assert_eq ! ( size, 11 ) ;
966+ } )
967+ }
968+
872969 #[ test]
873970 fn ttl ( ) {
874971 let ttl = 100 ;
0 commit comments