@@ -19,6 +19,7 @@ use io;
1919use net:: { ToSocketAddrs , SocketAddr , Shutdown } ;
2020use sys_common:: net as net_imp;
2121use sys_common:: { AsInner , FromInner } ;
22+ use time:: Duration ;
2223
2324/// A structure which represents a TCP stream between a local socket and a
2425/// remote socket.
@@ -139,6 +140,42 @@ impl TcpStream {
139140 pub fn set_keepalive ( & self , seconds : Option < u32 > ) -> io:: Result < ( ) > {
140141 self . 0 . set_keepalive ( seconds)
141142 }
143+
144+ /// Sets the read timeout to the timeout specified.
145+ ///
146+ /// If the value specified is `None`, then `read` calls will block
147+ /// indefinitely. It is an error to pass the zero `Duration` to this
148+ /// method.
149+ #[ unstable( feature = "socket_timeout" , reason = "RFC 1047 - recently added" ) ]
150+ pub fn set_read_timeout ( & self , dur : Option < Duration > ) -> io:: Result < ( ) > {
151+ self . 0 . set_read_timeout ( dur)
152+ }
153+
154+ /// Sets the write timeout to the timeout specified.
155+ ///
156+ /// If the value specified is `None`, then `write` calls will block
157+ /// indefinitely. It is an error to pass the zero `Duration` to this
158+ /// method.
159+ #[ unstable( feature = "socket_timeout" , reason = "RFC 1047 - recently added" ) ]
160+ pub fn set_write_timeout ( & self , dur : Option < Duration > ) -> io:: Result < ( ) > {
161+ self . 0 . set_write_timeout ( dur)
162+ }
163+
164+ /// Returns the read timeout of this socket.
165+ ///
166+ /// If the timeout is `None`, then `read` calls will block indefinitely.
167+ #[ unstable( feature = "socket_timeout" , reason = "RFC 1047 - recently added" ) ]
168+ pub fn read_timeout ( & self ) -> io:: Result < Option < Duration > > {
169+ self . 0 . read_timeout ( )
170+ }
171+
172+ /// Returns the write timeout of this socket.
173+ ///
174+ /// If the timeout is `None`, then `write` calls will block indefinitely.
175+ #[ unstable( feature = "socket_timeout" , reason = "RFC 1047 - recently added" ) ]
176+ pub fn write_timeout ( & self ) -> io:: Result < Option < Duration > > {
177+ self . 0 . write_timeout ( )
178+ }
142179}
143180
144181#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -262,6 +299,7 @@ mod tests {
262299 use net:: test:: { next_test_ip4, next_test_ip6} ;
263300 use sync:: mpsc:: channel;
264301 use sys_common:: AsInner ;
302+ use time:: Duration ;
265303 use thread;
266304
267305 fn each_ip ( f : & mut FnMut ( SocketAddr ) ) {
@@ -855,4 +893,69 @@ mod tests {
855893 stream_inner) ;
856894 assert_eq ! ( format!( "{:?}" , stream) , compare) ;
857895 }
896+
897+ #[ test]
898+ fn timeouts ( ) {
899+ let addr = next_test_ip4 ( ) ;
900+ let listener = t ! ( TcpListener :: bind( & addr) ) ;
901+
902+ let stream = t ! ( TcpStream :: connect( & ( "localhost" , addr. port( ) ) ) ) ;
903+ let dur = Duration :: new ( 15410 , 0 ) ;
904+
905+ assert_eq ! ( None , t!( stream. read_timeout( ) ) ) ;
906+
907+ t ! ( stream. set_read_timeout( Some ( dur) ) ) ;
908+ assert_eq ! ( Some ( dur) , t!( stream. read_timeout( ) ) ) ;
909+
910+ assert_eq ! ( None , t!( stream. write_timeout( ) ) ) ;
911+
912+ t ! ( stream. set_write_timeout( Some ( dur) ) ) ;
913+ assert_eq ! ( Some ( dur) , t!( stream. write_timeout( ) ) ) ;
914+
915+ t ! ( stream. set_read_timeout( None ) ) ;
916+ assert_eq ! ( None , t!( stream. read_timeout( ) ) ) ;
917+
918+ t ! ( stream. set_write_timeout( None ) ) ;
919+ assert_eq ! ( None , t!( stream. write_timeout( ) ) ) ;
920+ }
921+
922+ #[ test]
923+ fn test_read_timeout ( ) {
924+ let addr = next_test_ip4 ( ) ;
925+ let listener = t ! ( TcpListener :: bind( & addr) ) ;
926+
927+ let mut stream = t ! ( TcpStream :: connect( & ( "localhost" , addr. port( ) ) ) ) ;
928+ t ! ( stream. set_read_timeout( Some ( Duration :: from_millis( 10 ) ) ) ) ;
929+
930+ let mut buf = [ 0 ; 10 ] ;
931+ let wait = Duration :: span ( || {
932+ let kind = stream. read ( & mut buf) . err ( ) . expect ( "expected error" ) . kind ( ) ;
933+ assert ! ( kind == ErrorKind :: WouldBlock || kind == ErrorKind :: TimedOut ) ;
934+ } ) ;
935+ assert ! ( wait > Duration :: from_millis( 5 ) ) ;
936+ assert ! ( wait < Duration :: from_millis( 15 ) ) ;
937+ }
938+
939+ #[ test]
940+ fn test_read_with_timeout ( ) {
941+ let addr = next_test_ip4 ( ) ;
942+ let listener = t ! ( TcpListener :: bind( & addr) ) ;
943+
944+ let mut stream = t ! ( TcpStream :: connect( & ( "localhost" , addr. port( ) ) ) ) ;
945+ t ! ( stream. set_read_timeout( Some ( Duration :: from_millis( 10 ) ) ) ) ;
946+
947+ let mut other_end = t ! ( listener. accept( ) ) . 0 ;
948+ t ! ( other_end. write_all( b"hello world" ) ) ;
949+
950+ let mut buf = [ 0 ; 11 ] ;
951+ t ! ( stream. read( & mut buf) ) ;
952+ assert_eq ! ( b"hello world" , & buf[ ..] ) ;
953+
954+ let wait = Duration :: span ( || {
955+ let kind = stream. read ( & mut buf) . err ( ) . expect ( "expected error" ) . kind ( ) ;
956+ assert ! ( kind == ErrorKind :: WouldBlock || kind == ErrorKind :: TimedOut ) ;
957+ } ) ;
958+ assert ! ( wait > Duration :: from_millis( 5 ) ) ;
959+ assert ! ( wait < Duration :: from_millis( 15 ) ) ;
960+ }
858961}
0 commit comments