Goddess of Justice DB, the database used for storage on IzaroDFS
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

113 Zeilen
3.4 KiB

#include <chrono>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sstream>
#include <string>
#include <endian.hpp>
#include <network.hpp>
#include <array>
#include <thread>
#include <algorithm>
using namespace std::chrono_literals;
int main(int, char** argv){
int64_t offset=0;
std::array<int64_t, 4096> offsets;
std::array<int64_t, 4096> offsets_smooth;
std::array<int64_t, 4096> offset_variations;
size_t pos = 0;
int64_t max_offset_variation;
int64_t max_oscillation = 0;
int64_t min_ever = std::numeric_limits<int64_t>::max();
int64_t max_ever = 0;
std::stringstream ip_stream{argv[1]};
std::array<uint8_t, 4> ip;
std::string token;
std::getline(ip_stream, token, '.');
ip[0] = std::stoi(token);
std::getline(ip_stream, token, '.');
ip[1] = std::stoi(token);
std::getline(ip_stream, token, '.');
ip[2] = std::stoi(token);
std::getline(ip_stream, token, '.');
ip[3] = std::stoi(token);
uint16_t port = std::stoi(argv[2]);
auto soc = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = *(in_addr_t*)ip.data();
server.sin_port = htons(port);
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
setsockopt(soc, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
std::cerr << "Connecting..." <<std::endl;
connect(soc, (struct sockaddr*)&server, sizeof(server));
req_rep buffer;
uint64_t cnt = 0;
uint64_t old_time = 0;
while(true)
{
uint64_t tmp;
buffer.id = 16;
buffer.client_ts = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
send(soc, (void*)&buffer, (socklen_t)sizeof(req_rep), 0);
recv(soc, (void*)&buffer, (socklen_t)sizeof(req_rep), 0);
if(buffer.server_ts != old_time)
{
tmp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() - buffer.client_ts;
int64_t n_offset = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() - buffer.server_ts;
n_offset /= 2;
offset_variations[pos] = ((long long)(offset-n_offset));
if(cnt != 0)
{
offsets[pos] = n_offset;
} else {
offsets.fill(n_offset);
offsets_smooth.fill(n_offset);
}
max_offset_variation = std::max(*std::max_element(offset_variations.begin(), offset_variations.end()), std::abs((int64_t)*std::min_element(offset_variations.begin(), offset_variations.end())));
offset = (
7 * (std::accumulate(offsets_smooth.begin(), offsets_smooth.end(), 0)/offsets_smooth.size())
+ std::accumulate(offsets.begin(), offsets.end(), 0)/offsets.size()
) / 8;
offsets_smooth[pos] = offset;
pos=(pos+1)%offset_variations.size();
if(cnt > offsets.size()*2)
{
for(auto i : offsets_smooth)
for(auto j : offsets_smooth)
{
max_oscillation = std::max(
std::abs(i-j),
max_oscillation
);
}
min_ever = std::min(min_ever, offset);
max_ever = std::max(max_ever, offset);
}
else if (cnt < offsets.size()) {
offsets_smooth[pos] = n_offset;
}
old_time = buffer.server_ts;
std::cout << cnt << "\t"<< min_ever << "\t" << offset << "\t" << max_ever << "\t" << max_oscillation << "\t" << offset-n_offset << "\t" << max_offset_variation <<std::endl;
}
cnt++;
//std::this_thread::sleep_for(6ms);
}
}