@@ -20,7 +20,13 @@ char recvbuf[DEFAULT_BUFLEN];
2020char sendbuf[DEFAULT_BUFLEN];
2121bool keep_going = true ;
2222__int64 rec_bytes = 0 , sent_bytes = 0 ;
23- bool server = true ;
23+ enum _mode {
24+ server,
25+ client,
26+ child
27+ };
28+ enum _mode mode = server;
29+ bool rec_live = true , send_live = true ;
2430
2531
2632void prep_send_buf ()
@@ -40,6 +46,7 @@ DWORD WINAPI RecvThread(
4046 rec = recv (ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0 );
4147 rec_bytes += rec;
4248 }
49+ rec_live = false ;
4350 return 0 ;
4451}
4552
@@ -52,6 +59,7 @@ DWORD WINAPI SendThread(
5259 rec = send (ConnectSocket, sendbuf + rnd, DEFAULT_BUFLEN - rnd, 0 );
5360 sent_bytes += rec;
5461 }
62+ send_live = false ;
5563 return 0 ;
5664}
5765
@@ -64,7 +72,7 @@ int __cdecl main(int argc, char **argv)
6472 hints;
6573
6674 int iResult;
67-
75+
6876
6977 // Validate the parameters
7078 if ((argc < 2 ) || (strlen (argv[1 ]) > 1 )) {
@@ -73,7 +81,9 @@ int __cdecl main(int argc, char **argv)
7381 }
7482
7583 if (argv[1 ][0 ] == ' c' )
76- server = false ;
84+ mode = client;
85+ else if (argv[1 ][0 ] == ' o' )
86+ mode = child;
7787
7888 // Initialize Winsock
7989 iResult = WSAStartup (MAKEWORD (2 , 2 ), &wsaData);
@@ -87,15 +97,19 @@ int __cdecl main(int argc, char **argv)
8797 hints.ai_socktype = SOCK_STREAM;
8898 hints.ai_protocol = IPPROTO_TCP;
8999
100+ prep_send_buf ();
101+
90102 // Resolve the server address and port
91- iResult = getaddrinfo (argv[2 ], argv[3 ], &hints, &result);
92- if (iResult != 0 ) {
93- printf (" getaddrinfo failed with error: %d\n " , iResult);
94- WSACleanup ();
95- return 1 ;
103+ if (mode != child) {
104+ iResult = getaddrinfo (argv[2 ], argv[3 ], &hints, &result);
105+ if (iResult != 0 ) {
106+ printf (" getaddrinfo failed with error: %d\n " , iResult);
107+ WSACleanup ();
108+ return 1 ;
109+ }
96110 }
97111
98- if (!server ) {
112+ if (mode == client ) {
99113 // Attempt to connect to an address until one succeeds
100114 for (ptr = result; ptr != NULL ; ptr = ptr->ai_next ) {
101115
@@ -124,7 +138,11 @@ int __cdecl main(int argc, char **argv)
124138 return 1 ;
125139 }
126140 }
141+ else if (mode == child) {
142+ ConnectSocket = atoi (argv[2 ]);
143+ }
127144 else {
145+
128146 SOCKET ListenSocket;
129147 // Create a SOCKET for connecting to server
130148 ListenSocket = socket (result->ai_family , result->ai_socktype , result->ai_protocol );
@@ -154,17 +172,34 @@ int __cdecl main(int argc, char **argv)
154172 }
155173
156174 // Accept a client socket
157- ConnectSocket = accept (ListenSocket, NULL , NULL );
158- if (ConnectSocket == INVALID_SOCKET) {
159- printf (" accept failed with error: %d\n " , WSAGetLastError ());
160- closesocket (ListenSocket);
161- WSACleanup ();
162- return 1 ;
175+ while (1 ) {
176+ ConnectSocket = accept (ListenSocket, NULL , NULL );
177+ if (ConnectSocket == INVALID_SOCKET) {
178+ printf (" accept failed with error: %d\n " , WSAGetLastError ());
179+ closesocket (ListenSocket);
180+ WSACleanup ();
181+ return 1 ;
182+ }
183+ if (!SetHandleInformation ((HANDLE)ConnectSocket, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
184+ printf (" unable to set inheritance on socket handle: %p\n " , ConnectSocket);
185+ int sock_int = ConnectSocket & 0xffffffff ;
186+ char cmd[MAX_PATH];
187+ STARTUPINFOA si;
188+ PROCESS_INFORMATION pi;
189+ ZeroMemory (&si, sizeof (si)); ZeroMemory (&pi, sizeof (pi));
190+ si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
191+ si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
192+ si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
193+ sprintf (cmd, " %s o %d" , argv[0 ], sock_int);
194+ // spawn a child
195+ if (!CreateProcessA (NULL , cmd, NULL , NULL , TRUE , CREATE_NEW_CONSOLE, NULL , NULL , &si, &pi))
196+ printf (" child creation failed: %d\n " , GetLastError ());
197+ closesocket (ConnectSocket);
163198 }
164- // No longer need server socket
165- closesocket (ListenSocket);
166199
167200
201+ // No longer need server socket
202+ closesocket (ListenSocket);
168203 }
169204
170205 freeaddrinfo (result);
@@ -201,23 +236,25 @@ int __cdecl main(int argc, char **argv)
201236 return 1 ;
202237 }
203238
204- printf (" \t Recv(Kb/s) \t\t Sent(Kb/s) \n " );
239+ printf (" \t %-20s %-20s \n " , " Recv(Kbps) " , " Send(Kbps) " );
205240 __int64 last_recv = 0 ;
206241 __int64 last_send = 0 ;
207- while (1 ) {
242+ while (rec_live || send_live ) {
208243 if (WAIT_OBJECT_0 != WaitForSingleObject (timer, INFINITE)) {
209244 printf (" wait failed %d\n " , GetLastError ());
210245 break ;
211246 }
212247 __int64 now_recv = rec_bytes;
213248 __int64 now_send = sent_bytes;
214249
215- printf (" \r\t %lld \t\t %lld " , (now_recv - last_recv) / 2048 , (now_send - last_send) / 2048 );
250+ printf (" \r\t %-20lld %-20lld " , (now_recv - last_recv) / ( 2 * 1048 ) , (now_send - last_send) / ( 2 * 1048 ) );
216251 last_recv = now_recv;
217252 last_send = now_send;
218253
219254 }
220255
256+ printf (" \n\n " );
257+
221258 closesocket (ConnectSocket);
222259 WSACleanup ();
223260
0 commit comments