@@ -7,96 +7,161 @@ use function Async\spawn;
77use function Async \awaitAll ;
88use function Async \delay ;
99
10- echo "Start concurrent UDP operations test \n" ;
11-
12- // Create multiple UDP servers
13- $ servers = [];
14- $ server_addresses = [];
15-
16- for ($ i = 0 ; $ i < 3 ; $ i ++) {
17- $ servers [] = spawn (function () use ($ i , &$ server_addresses ) {
18- $ socket = stream_socket_server ("udp://127.0.0.1:0 " , $ errno , $ errstr );
19- if (!$ socket ) {
20- echo "Server $ i: failed to create socket \n" ;
21- return ;
22- }
10+ $ output = [];
11+
12+ $ output ['1 ' ] = "Start concurrent UDP operations test " ;
13+
14+ $ server1_address = null ;
15+ $ server2_address = null ;
16+
17+ // Server1 coroutine
18+ $ server1 = spawn (function () use (&$ server1_address , &$ output ) {
19+ $ output ['2 ' ] = "Server1: creating UDP socket " ;
20+ $ socket = stream_socket_server ("udp://127.0.0.1:0 " , $ errno , $ errstr , STREAM_SERVER_BIND );
21+ if (!$ socket ) {
22+ $ output ['2a ' ] = "Server1: failed to create socket: $ errstr " ;
23+ return ;
24+ }
25+
26+ $ address = stream_socket_get_name ($ socket , false );
27+ $ server1_address = "udp:// $ address " ;
28+ $ output ['3 ' ] = "Server1: listening on $ server1_address " ;
29+
30+ // Wait for incoming data
31+ $ output ['5 ' ] = "Server1: waiting for UDP data " ;
32+ $ data = stream_socket_recvfrom ($ socket , 1024 , 0 , $ peer );
33+ $ output ['7 ' ] = "Server1: received ' $ data' from $ peer " ;
34+
35+ // Send response back
36+ $ response = "Hello from UDP server1 " ;
37+ $ bytes = stream_socket_sendto ($ socket , $ response , 0 , $ peer );
38+ $ output ['8 ' ] = "Server1: sent $ bytes bytes response " ;
39+
40+ fclose ($ socket );
41+ return $ server1_address ;
42+ });
43+
44+ // Server2 coroutine
45+ $ server2 = spawn (function () use (&$ server2_address , &$ output ) {
46+ $ output ['2b ' ] = "Server2: creating UDP socket " ;
47+ $ socket = stream_socket_server ("udp://127.0.0.1:0 " , $ errno , $ errstr , STREAM_SERVER_BIND );
48+ if (!$ socket ) {
49+ $ output ['2c ' ] = "Server2: failed to create socket: $ errstr " ;
50+ return ;
51+ }
2352
24- $ address = stream_socket_get_name ($ socket , false );
25- $ server_addresses [ $ i ] = $ address ;
26- echo " Server $ i : listening on $ address \n " ;
53+ $ address = stream_socket_get_name ($ socket , false );
54+ $ server2_address = " udp:// $ address" ;
55+ $ output [ ' 4 ' ] = " Server2 : listening on $ server2_address " ;
2756
28- // Handle multiple clients
29- for ( $ j = 0 ; $ j < 2 ; $ j ++) {
30- $ data = stream_socket_recvfrom ($ socket , 1024 , 0 , $ peer );
31- echo " Server $ i : received ' $ data' from client \n " ;
57+ // Wait for incoming data
58+ $ output [ ' 5b ' ] = " Server2: waiting for UDP data " ;
59+ $ data = stream_socket_recvfrom ($ socket , 1024 , 0 , $ peer );
60+ $ output [ ' 7b ' ] = " Server2 : received '$ data' from $ peer " ;
3261
33- $ response = "Response from server $ i to message $ j " ;
34- stream_socket_sendto ($ socket , $ response , 0 , $ peer );
62+ // Send response back
63+ $ response = "Hello from UDP server2 " ;
64+ $ bytes = stream_socket_sendto ($ socket , $ response , 0 , $ peer );
65+ $ output ['8b ' ] = "Server2: sent $ bytes bytes response " ;
66+
67+ fclose ($ socket );
68+ return $ server2_address ;
69+ });
70+
71+ // Client1 coroutine
72+ $ client1 = spawn (function () use (&$ server1_address , &$ output ) {
73+ // Wait for server1 to start
74+ for ($ attempts = 0 ; $ attempts < 10 ; $ attempts ++) {
75+ delay (10 );
76+ if ($ server1_address ) {
77+ break ;
3578 }
79+ }
3680
37- fclose ($ socket );
38- return $ address ;
39- });
40- }
81+ if (!$ server1_address ) {
82+ throw new Exception ("Client1: failed to get server1 address after 10 attempts " );
83+ }
4184
42- // Create multiple clients for each server
43- $ clients = [];
44- for ($ i = 0 ; $ i < 3 ; $ i ++) {
45- for ($ j = 0 ; $ j < 2 ; $ j ++) {
46- $ clients [] = spawn (function () use ($ i , $ j , &$ server_addresses ) {
47- // Wait for server address with retry logic
48- $ address = null ;
49- for ($ attempts = 0 ; $ attempts < 5 ; $ attempts ++) {
50- delay (10 );
51- if (isset ($ server_addresses [$ i ])) {
52- $ address = $ server_addresses [$ i ];
53- break ;
54- }
55- }
56-
57- if (!$ address ) {
58- throw new Exception ("Client $ i- $ j: server address not ready after 5 attempts " );
59- }
60-
61- $ socket = stream_socket_client ($ address , $ errno , $ errstr );
62- if (!$ socket ) {
63- echo "Client $ i- $ j: failed to connect \n" ;
64- return ;
65- }
66-
67- $ message = "Message from client $ i- $ j " ;
68- stream_socket_sendto ($ socket , $ message );
69-
70- $ response = stream_socket_recvfrom ($ socket , 1024 );
71- echo "Client $ i- $ j: received ' $ response' \n" ;
72-
73- fclose ($ socket );
74- });
85+ $ output ['6 ' ] = "Client1: connecting to $ server1_address " ;
86+ $ socket = stream_socket_client ($ server1_address , $ errno , $ errstr );
87+ if (!$ socket ) {
88+ $ output ['6a ' ] = "Client1: failed to connect: $ errstr " ;
89+ return ;
7590 }
76- }
7791
78- // Background worker
79- $ worker = spawn (function () {
80- for ($ i = 0 ; $ i < 5 ; $ i ++) {
81- echo "Worker: iteration $ i \n" ;
92+ // Send data to server1
93+ $ message = "Hello from UDP client1 " ;
94+ $ bytes = stream_socket_sendto ($ socket , $ message );
95+ $ output ['6b ' ] = "Client1: sent $ bytes bytes " ;
96+
97+ // Receive response
98+ $ response = stream_socket_recvfrom ($ socket , 1024 );
99+ $ output ['9 ' ] = "Client1: received ' $ response' " ;
100+
101+ fclose ($ socket );
102+ });
103+
104+ // Client2 coroutine
105+ $ client2 = spawn (function () use (&$ server2_address , &$ output ) {
106+ // Wait for server2 to start
107+ for ($ attempts = 0 ; $ attempts < 10 ; $ attempts ++) {
82108 delay (10 );
109+ if ($ server2_address ) {
110+ break ;
111+ }
112+ }
113+
114+ if (!$ server2_address ) {
115+ throw new Exception ("Client2: failed to get server2 address after 10 attempts " );
83116 }
117+
118+ $ output ['6c ' ] = "Client2: connecting to $ server2_address " ;
119+ $ socket = stream_socket_client ($ server2_address , $ errno , $ errstr );
120+ if (!$ socket ) {
121+ $ output ['6d ' ] = "Client2: failed to connect: $ errstr " ;
122+ return ;
123+ }
124+
125+ // Send data to server2
126+ $ message = "Hello from UDP client2 " ;
127+ $ bytes = stream_socket_sendto ($ socket , $ message );
128+ $ output ['6e ' ] = "Client2: sent $ bytes bytes " ;
129+
130+ // Receive response
131+ $ response = stream_socket_recvfrom ($ socket , 1024 );
132+ $ output ['9b ' ] = "Client2: received ' $ response' " ;
133+
134+ fclose ($ socket );
84135});
85136
86- awaitAll (array_merge ($ servers , $ clients , [$ worker ]));
87- echo "End concurrent UDP operations test \n" ;
137+ awaitAll ([$ server1 , $ server2 , $ client1 , $ client2 ]);
138+ $ output ['z ' ] = "End concurrent UDP operations test " ;
139+
140+ // Sort output by keys to ensure deterministic test results
141+ ksort ($ output );
142+
143+ // Output sorted results
144+ foreach ($ output as $ line ) {
145+ echo $ line . "\n" ;
146+ }
88147
89148?>
90149--EXPECTF--
91150Start concurrent UDP operations test
92- Server 0: listening on udp://127.0.0.1:%d
93- Server 1: listening on udp://127.0.0.1:%d
94- Server 2: listening on udp://127.0.0.1:%d
95- Worker: iteration 0
96- %a
97- Server %d: received 'Message from client %d-%d' from client
98- Client %d-%d: received 'Response from server %d to message %d'
99- %a
100- Worker: iteration %d
101- %a
151+ Server1: creating UDP socket
152+ Server2: creating UDP socket
153+ Server1: listening on udp://127.0.0.1:%d
154+ Server2: listening on udp://127.0.0.1:%d
155+ Server1: waiting for UDP data
156+ Server2: waiting for UDP data
157+ Client1: connecting to udp://127.0.0.1:%d
158+ Client1: sent 22 bytes
159+ Client2: connecting to udp://127.0.0.1:%d
160+ Client2: sent 22 bytes
161+ Server1: received 'Hello from UDP client1' from 127.0.0.1:%d
162+ Server2: received 'Hello from UDP client2' from 127.0.0.1:%d
163+ Server1: sent 22 bytes response
164+ Server2: sent 22 bytes response
165+ Client1: received 'Hello from UDP server1'
166+ Client2: received 'Hello from UDP server2'
102167End concurrent UDP operations test
0 commit comments