Goddess of Justice DB, the database used for storage on IzaroDFS
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

113 строки
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);
}
}