1+
2+
3+ #define WIN32_LEAN_AND_MEAN
4+
5+ #include < windows.h>
6+ #include < winsock2.h>
7+ #include < ws2tcpip.h>
8+ #include < stdlib.h>
9+ #include < stdio.h>
10+
11+
12+ // Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
13+ #pragma comment (lib, "Ws2_32.lib")
14+ #pragma comment (lib, "Mswsock.lib")
15+ #pragma comment (lib, "AdvApi32.lib")
16+
17+
18+ #define DEFAULT_BUFLEN 512 *1024 // 512 KB
19+ char recvbuf[DEFAULT_BUFLEN];
20+ char sendbuf[DEFAULT_BUFLEN];
21+ bool keep_going = true ;
22+ __int64 rec_bytes = 0 , sent_bytes = 0 ;
23+ bool server = true ;
24+
25+
26+ void prep_send_buf ()
27+ {
28+ int *buf = (int *)sendbuf;
29+ for (int i = 0 ; i < DEFAULT_BUFLEN; i += sizeof (int ))
30+ *buf++ = rand ();
31+ }
32+
33+ SOCKET ConnectSocket = INVALID_SOCKET;
34+
35+ DWORD WINAPI RecvThread (
36+ _In_ LPVOID lpParameter
37+ ) {
38+ int rec = 1 ;
39+ while (keep_going && (rec>0 )) {
40+ rec = recv (ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0 );
41+ rec_bytes += rec;
42+ }
43+ return 0 ;
44+ }
45+
46+ DWORD WINAPI SendThread (
47+ _In_ LPVOID lpParameter
48+ ) {
49+ int rec = 1 , rnd;
50+ while (keep_going && (rec>0 )) {
51+ rnd = rand ();
52+ rec = send (ConnectSocket, sendbuf + rnd, DEFAULT_BUFLEN - rnd, 0 );
53+ sent_bytes += rec;
54+ }
55+ return 0 ;
56+ }
57+
58+ int __cdecl main (int argc, char **argv)
59+ {
60+ WSADATA wsaData;
61+
62+ struct addrinfo *result = NULL ,
63+ *ptr = NULL ,
64+ hints;
65+
66+ int iResult;
67+
68+
69+ // Validate the parameters
70+ if ((argc < 2 ) || (strlen (argv[1 ]) > 1 )) {
71+ printf (" usage: %s [c|s] IP port\n " , argv[0 ]);
72+ return 1 ;
73+ }
74+
75+ if (argv[1 ][0 ] == ' c' )
76+ server = false ;
77+
78+ // Initialize Winsock
79+ iResult = WSAStartup (MAKEWORD (2 , 2 ), &wsaData);
80+ if (iResult != 0 ) {
81+ printf (" WSAStartup failed with error: %d\n " , iResult);
82+ return 1 ;
83+ }
84+
85+ ZeroMemory (&hints, sizeof (hints));
86+ hints.ai_family = AF_UNSPEC;
87+ hints.ai_socktype = SOCK_STREAM;
88+ hints.ai_protocol = IPPROTO_TCP;
89+
90+ // 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 ;
96+ }
97+
98+ if (!server) {
99+ // Attempt to connect to an address until one succeeds
100+ for (ptr = result; ptr != NULL ; ptr = ptr->ai_next ) {
101+
102+ // Create a SOCKET for connecting to server
103+ ConnectSocket = socket (ptr->ai_family , ptr->ai_socktype ,
104+ ptr->ai_protocol );
105+ if (ConnectSocket == INVALID_SOCKET) {
106+ printf (" socket failed with error: %ld\n " , WSAGetLastError ());
107+ WSACleanup ();
108+ return 1 ;
109+ }
110+
111+ // Connect to server.
112+ iResult = connect (ConnectSocket, ptr->ai_addr , (int )ptr->ai_addrlen );
113+ if (iResult == SOCKET_ERROR) {
114+ closesocket (ConnectSocket);
115+ ConnectSocket = INVALID_SOCKET;
116+ continue ;
117+ }
118+ break ;
119+ }
120+
121+ if (ConnectSocket == INVALID_SOCKET) {
122+ printf (" Unable to connect to server!\n " );
123+ WSACleanup ();
124+ return 1 ;
125+ }
126+ }
127+ else {
128+ SOCKET ListenSocket;
129+ // Create a SOCKET for connecting to server
130+ ListenSocket = socket (result->ai_family , result->ai_socktype , result->ai_protocol );
131+ if (ListenSocket == INVALID_SOCKET) {
132+ printf (" socket failed with error: %ld\n " , WSAGetLastError ());
133+ freeaddrinfo (result);
134+ WSACleanup ();
135+ return 1 ;
136+ }
137+
138+ // Setup the TCP listening socket
139+ iResult = bind (ListenSocket, result->ai_addr , (int )result->ai_addrlen );
140+ if (iResult == SOCKET_ERROR) {
141+ printf (" bind failed with error: %d\n " , WSAGetLastError ());
142+ freeaddrinfo (result);
143+ closesocket (ListenSocket);
144+ WSACleanup ();
145+ return 1 ;
146+ }
147+
148+ iResult = listen (ListenSocket, SOMAXCONN);
149+ if (iResult == SOCKET_ERROR) {
150+ printf (" listen failed with error: %d\n " , WSAGetLastError ());
151+ closesocket (ListenSocket);
152+ WSACleanup ();
153+ return 1 ;
154+ }
155+
156+ // 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 ;
163+ }
164+ // No longer need server socket
165+ closesocket (ListenSocket);
166+
167+
168+ }
169+
170+ freeaddrinfo (result);
171+
172+ HANDLE rt = CreateThread (NULL , 0 , RecvThread, NULL , 0 , NULL );
173+ if (rt == NULL ) {
174+ printf (" Unable to create read thread!\n " );
175+ closesocket (ConnectSocket);
176+ WSACleanup ();
177+ return 1 ;
178+ }
179+
180+ HANDLE wt = CreateThread (NULL , 0 , SendThread, NULL , 0 , NULL );
181+ if (wt == NULL ) {
182+ printf (" Unable to create send thread!\n " );
183+ closesocket (ConnectSocket);
184+ WSACleanup ();
185+ return 1 ;
186+ }
187+
188+ HANDLE timer = CreateWaitableTimer (NULL , FALSE , NULL );
189+ if (timer == NULL ){
190+ printf (" Unable to create timer!\n " );
191+ closesocket (ConnectSocket);
192+ WSACleanup ();
193+ return 1 ;
194+ }
195+ LARGE_INTEGER liDueTime;
196+ liDueTime.QuadPart = 0 ;
197+ if (!SetWaitableTimer (timer, &liDueTime, 2000 , NULL , NULL , false )) {
198+ printf (" Unable to set timer!\n " );
199+ closesocket (ConnectSocket);
200+ WSACleanup ();
201+ return 1 ;
202+ }
203+
204+ printf (" \t Recv(Kb/s) \t\t Sent(Kb/s)\n " );
205+ __int64 last_recv = 0 ;
206+ __int64 last_send = 0 ;
207+ while (1 ) {
208+ if (WAIT_OBJECT_0 != WaitForSingleObject (timer, INFINITE)) {
209+ printf (" wait failed %d\n " , GetLastError ());
210+ break ;
211+ }
212+ __int64 now_recv = rec_bytes;
213+ __int64 now_send = sent_bytes;
214+
215+ printf (" \r\t %lld \t\t %lld" , (now_recv - last_recv) / 2048 , (now_send - last_send) / 2048 );
216+ last_recv = now_recv;
217+ last_send = now_send;
218+
219+ }
220+
221+ closesocket (ConnectSocket);
222+ WSACleanup ();
223+
224+ return 0 ;
225+ }
0 commit comments