@@ -19,6 +19,7 @@ use io;
19
19
use net:: { ToSocketAddrs , SocketAddr , Shutdown } ;
20
20
use sys_common:: net as net_imp;
21
21
use sys_common:: { AsInner , FromInner } ;
22
+ use time:: Duration ;
22
23
23
24
/// A structure which represents a TCP stream between a local socket and a
24
25
/// remote socket.
@@ -139,6 +140,42 @@ impl TcpStream {
139
140
pub fn set_keepalive ( & self , seconds : Option < u32 > ) -> io:: Result < ( ) > {
140
141
self . 0 . set_keepalive ( seconds)
141
142
}
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
+ }
142
179
}
143
180
144
181
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -262,6 +299,7 @@ mod tests {
262
299
use net:: test:: { next_test_ip4, next_test_ip6} ;
263
300
use sync:: mpsc:: channel;
264
301
use sys_common:: AsInner ;
302
+ use time:: Duration ;
265
303
use thread;
266
304
267
305
fn each_ip ( f : & mut FnMut ( SocketAddr ) ) {
@@ -855,4 +893,69 @@ mod tests {
855
893
stream_inner) ;
856
894
assert_eq ! ( format!( "{:?}" , stream) , compare) ;
857
895
}
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
+ assert_eq ! ( ErrorKind :: WouldBlock ,
933
+ stream. read( & mut buf) . err( ) . expect( "expected error" ) . kind( ) ) ;
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
+ assert_eq ! ( ErrorKind :: WouldBlock ,
956
+ stream. read( & mut buf) . err( ) . expect( "expected error" ) . kind( ) ) ;
957
+ } ) ;
958
+ assert ! ( wait > Duration :: from_millis( 5 ) ) ;
959
+ assert ! ( wait < Duration :: from_millis( 15 ) ) ;
960
+ }
858
961
}
0 commit comments