-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient_mock.cpp
114 lines (88 loc) · 3.51 KB
/
client_mock.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* This program measures the throughput of the incoming socket data stream on the specified port.
* Used to benchmark the data generator in an isolated context.
* Usage: client_mock <port-number>
*
* Run the data generator that writes to the socket (the same port number). Only one port can be measured within one execution.
* When the data generator closes the TCP connection, the client_mock will print the measured results.
*/
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <chrono>
#include <cerrno>
#include <iomanip>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
int bufferSize = 4096 * 8 * 8 * 8;
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cerr << "Usage: ./server_mock <port_number>\n";
exit(1);
}
// Get port number as command line argument
int port = atoi(argv[1]);
sockaddr_in server_addr{};
memset(&server_addr, 0, sizeof(sockaddr_in));
int socketDesc = socket(AF_INET, SOCK_STREAM, 0);
if (socketDesc == -1) {
std::cerr << "Error. Could not create socket: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
// Increase TCP receive buffer size
if (setsockopt(socketDesc, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) == -1) {
std::cerr << "ERROR: Setting send buffer size failed.\n";
}
// Prevents "Address already used"-error on restart
int option = 1;
setsockopt(socketDesc, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
int res = connect(socketDesc, (sockaddr*)&server_addr, sizeof(server_addr));
if (res == -1) {
std::cerr << "Error. Could not connect to server socket: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
std::cout << "Connected to TCP socket port " << port << ".\n";
char buffer[bufferSize];
size_t total_bytes_read = 0;
bool initial_bytes_received = false;
std::chrono::time_point<std::chrono::steady_clock> t1;
std::chrono::time_point<std::chrono::steady_clock> t2;
std::string surplus;
while (true) {
strncpy(buffer, surplus.c_str(), surplus.size());
int bytesRead = recv(socketDesc, buffer + surplus.size(), bufferSize - surplus.size(), 0);
if (bytesRead == -1) {
std::cerr << "ERROR: Receiving bytes from server failed: " << strerror(errno) << "\n";
exit(6);
} else if (bytesRead + surplus.size() == 0) {
t2 = std::chrono::steady_clock::now();
std::cout << "SUCCESS: Socket Stream closed. Peer performed an orderly shutdown.\n";
break;
}
if (!initial_bytes_received) {
t1 = std::chrono::steady_clock::now();
initial_bytes_received = true;
}
total_bytes_read += bytesRead;
int nextStart = 0;
for (int i = 0; i < bytesRead; i++) {
if (buffer[i] == '\n') {
nextStart = i + 1;
}
}
surplus.assign(buffer + nextStart, bytesRead - nextStart);
}
std::cout << std::fixed << std::setprecision(9);
double sec = std::chrono::duration<double>(t2 - t1).count();
std::cout << "Time Duration: " << sec << "s\n";
std::cout << "Total Bytes Read: " << total_bytes_read << "B\n";
std::cout << "Total Throughput: " << (total_bytes_read / 1000000.0) / sec << " MB/s\n";
close(socketDesc);
return 0;
}