@@ -20,7 +20,13 @@ char recvbuf[DEFAULT_BUFLEN];
20
20
char sendbuf[DEFAULT_BUFLEN];
21
21
bool keep_going = true ;
22
22
__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 ;
24
30
25
31
26
32
void prep_send_buf ()
@@ -40,6 +46,7 @@ DWORD WINAPI RecvThread(
40
46
rec = recv (ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0 );
41
47
rec_bytes += rec;
42
48
}
49
+ rec_live = false ;
43
50
return 0 ;
44
51
}
45
52
@@ -52,6 +59,7 @@ DWORD WINAPI SendThread(
52
59
rec = send (ConnectSocket, sendbuf + rnd, DEFAULT_BUFLEN - rnd, 0 );
53
60
sent_bytes += rec;
54
61
}
62
+ send_live = false ;
55
63
return 0 ;
56
64
}
57
65
@@ -64,7 +72,7 @@ int __cdecl main(int argc, char **argv)
64
72
hints;
65
73
66
74
int iResult;
67
-
75
+
68
76
69
77
// Validate the parameters
70
78
if ((argc < 2 ) || (strlen (argv[1 ]) > 1 )) {
@@ -73,7 +81,9 @@ int __cdecl main(int argc, char **argv)
73
81
}
74
82
75
83
if (argv[1 ][0 ] == ' c' )
76
- server = false ;
84
+ mode = client;
85
+ else if (argv[1 ][0 ] == ' o' )
86
+ mode = child;
77
87
78
88
// Initialize Winsock
79
89
iResult = WSAStartup (MAKEWORD (2 , 2 ), &wsaData);
@@ -87,15 +97,19 @@ int __cdecl main(int argc, char **argv)
87
97
hints.ai_socktype = SOCK_STREAM;
88
98
hints.ai_protocol = IPPROTO_TCP;
89
99
100
+ prep_send_buf ();
101
+
90
102
// 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
+ }
96
110
}
97
111
98
- if (!server ) {
112
+ if (mode == client ) {
99
113
// Attempt to connect to an address until one succeeds
100
114
for (ptr = result; ptr != NULL ; ptr = ptr->ai_next ) {
101
115
@@ -124,7 +138,11 @@ int __cdecl main(int argc, char **argv)
124
138
return 1 ;
125
139
}
126
140
}
141
+ else if (mode == child) {
142
+ ConnectSocket = atoi (argv[2 ]);
143
+ }
127
144
else {
145
+
128
146
SOCKET ListenSocket;
129
147
// Create a SOCKET for connecting to server
130
148
ListenSocket = socket (result->ai_family , result->ai_socktype , result->ai_protocol );
@@ -154,17 +172,34 @@ int __cdecl main(int argc, char **argv)
154
172
}
155
173
156
174
// 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);
163
198
}
164
- // No longer need server socket
165
- closesocket (ListenSocket);
166
199
167
200
201
+ // No longer need server socket
202
+ closesocket (ListenSocket);
168
203
}
169
204
170
205
freeaddrinfo (result);
@@ -201,23 +236,25 @@ int __cdecl main(int argc, char **argv)
201
236
return 1 ;
202
237
}
203
238
204
- printf (" \t Recv(Kb/s) \t\t Sent(Kb/s) \n " );
239
+ printf (" \t %-20s %-20s \n " , " Recv(Kbps) " , " Send(Kbps) " );
205
240
__int64 last_recv = 0 ;
206
241
__int64 last_send = 0 ;
207
- while (1 ) {
242
+ while (rec_live || send_live ) {
208
243
if (WAIT_OBJECT_0 != WaitForSingleObject (timer, INFINITE)) {
209
244
printf (" wait failed %d\n " , GetLastError ());
210
245
break ;
211
246
}
212
247
__int64 now_recv = rec_bytes;
213
248
__int64 now_send = sent_bytes;
214
249
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 ) );
216
251
last_recv = now_recv;
217
252
last_send = now_send;
218
253
219
254
}
220
255
256
+ printf (" \n\n " );
257
+
221
258
closesocket (ConnectSocket);
222
259
WSACleanup ();
223
260
0 commit comments