22
33import struct , time , socket , select
44
5+ try :
6+ import errno
7+ except ImportError :
8+ print ("SKIP" )
9+ raise SystemExit
10+
511PORT = 8000
612
713
@@ -18,27 +24,49 @@ def instance0():
1824 s .bind (socket .getaddrinfo ("0.0.0.0" , PORT )[0 ][- 1 ])
1925 s .listen (1 )
2026 multitest .next ()
21- s2 , _ = s .accept ()
22- s2 .setblocking (False )
23- poll = select .poll ()
24- poll .register (s2 , select .POLLIN )
25- time .sleep (0.4 )
26- print (convert_poll_list (poll .poll (1000 )))
27- # TODO: the following recv don't work with lwip, it abandons data upon TCP RST
28- try :
29- print (s2 .recv (10 ))
27+
28+ for iteration in range (2 ):
29+ print ("server iteration" , iteration )
30+
31+ # Accept a connection from the client.
32+ s2 , _ = s .accept ()
33+ s2 .setblocking (False )
34+
35+ # Create a poller for the connected socket.
36+ poll = select .poll ()
37+ poll .register (s2 , select .POLLIN )
38+
39+ # Wait for the client to send data and issue a TCP RST.
40+ for _ in range (10 ):
41+ if select .POLLIN | select .POLLERR | select .POLLHUP in convert_poll_list (
42+ poll .poll (1000 )
43+ ):
44+ break
45+ time .sleep (0.1 )
3046 print (convert_poll_list (poll .poll (1000 )))
31- print (s2 .recv (10 ))
47+
48+ # On the second test, drain the incoming data.
49+ if iteration == 1 :
50+ for _ in range (5 ):
51+ try :
52+ print (s2 .recv (10 ))
53+ except OSError as er :
54+ # This error should only happen on the 3rd recv.
55+ print ("ECONNRESET:" , er .errno == errno .ECONNRESET )
56+ print (convert_poll_list (poll .poll (1000 )))
57+
58+ # Close the connection to the client.
59+ s2 .close ()
3260 print (convert_poll_list (poll .poll (1000 )))
33- print (s2 .recv (10 ))
61+
62+ # Try to read more data from the closed socket, to make sure the error code is correct.
63+ try :
64+ print (s2 .recv (10 ))
65+ except OSError as er :
66+ print ("EBADF:" , er .errno == errno .EBADF )
3467 print (convert_poll_list (poll .poll (1000 )))
35- except OSError as er :
36- print (er .errno )
37- print (convert_poll_list (poll .poll (1000 )))
38- # TODO lwip raises here but apparently it shouldn't
39- print (s2 .recv (10 ))
40- print (convert_poll_list (poll .poll (1000 )))
41- s2 .close ()
68+
69+ # Close the listening socket.
4270 s .close ()
4371
4472
@@ -47,11 +75,13 @@ def instance1():
4775 if not hasattr (socket , "SO_LINGER" ):
4876 multitest .skip ()
4977 multitest .next ()
50- s = socket .socket (socket .AF_INET , socket .SOCK_STREAM , 0 )
51- s .connect (socket .getaddrinfo (IP , PORT )[0 ][- 1 ])
52- lgr_onoff = 1
53- lgr_linger = 0
54- s .setsockopt (socket .SOL_SOCKET , socket .SO_LINGER , struct .pack ("ii" , lgr_onoff , lgr_linger ))
55- s .send (b"GET / HTTP/1.0\r \n \r \n " )
56- time .sleep (0.2 )
57- s .close () # This issues a TCP RST since we've set the linger option
78+ for iteration in range (2 ):
79+ print ("client iteration" , iteration )
80+ s = socket .socket (socket .AF_INET , socket .SOCK_STREAM , 0 )
81+ s .connect (socket .getaddrinfo (IP , PORT )[0 ][- 1 ])
82+ lgr_onoff = 1
83+ lgr_linger = 0
84+ s .setsockopt (socket .SOL_SOCKET , socket .SO_LINGER , struct .pack ("ii" , lgr_onoff , lgr_linger ))
85+ s .send (b"GET / HTTP/1.0\r \n \r \n " )
86+ time .sleep (0.2 )
87+ s .close () # This issues a TCP RST since we've set the linger option
0 commit comments