Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么';这是以编程方式检查年份是否更改的最有效方法_C++_C++11_Time_Sniffing - Fatal编程技术网

C++ 什么';这是以编程方式检查年份是否更改的最有效方法

C++ 什么';这是以编程方式检查年份是否更改的最有效方法,c++,c++11,time,sniffing,C++,C++11,Time,Sniffing,我试图从NIC捕获数据包,并将数据包负载的一部分保存为字符串 数据包必须存储的部分是它的日志时间,称为SysLog。每个数据包都有以下格式的系统日志: Nov 01 03 14:50:25 TCP...[other parts of packet Payload] 可以看出,数据包SysLog没有年份号。我的程序必须全年运行,所以我需要将年份号添加到数据包SysLog中,并将SysLog转换为epoch time。我必须存储的最后一个字符串如下所示: 1478175389-TCP, …. 我

我试图从NIC捕获数据包,并将数据包负载的一部分保存为字符串

数据包必须存储的部分是它的日志时间,称为SysLog。每个数据包都有以下格式的系统日志:

Nov 01 03 14:50:25 TCP...[other parts of packet Payload]
可以看出,数据包SysLog没有年份号。我的程序必须全年运行,所以我需要将年份号添加到数据包SysLog中,并将SysLog转换为epoch time。我必须存储的最后一个字符串如下所示:

1478175389-TCP, ….
我使用以下代码将Syslog转换为EpochTime

tm* tm_date = new tm();
Std ::string time = Current_Year;
time += " ";
time += packet.substr(0,18);
strptime(time.c_str(), "%Y %b %d %T", tm_date);
EpochTime = timegm(tm_date);
本年度方法:

std::string    currentYear() {
    std::stringstream now;
    auto tp = std::chrono::system_clock::now();
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
    size_t modulo = ms.count() % 1000;
    time_t seconds = std::chrono::duration_cast<std::chrono::seconds>(ms).count();
#if HAS_STD_PUT_TIME
#else
    char buffer[25]; // holds "2013-12-01 21:31:42"
    if (strftime(buffer, 25, "%Y", localtime(&seconds))) {
        now << buffer;
    }
#endif // HAS_STD_PUT_TIME
    return now.str();
}
std::string currentYear(){
std::stringstream现在;
自动tp=std::chrono::system_clock::now();
自动ms=std::chrono::duration_cast(tp.time_-since_-epoch());
大小模数=毫秒计数()%1000;
time_t seconds=std::chrono::duration_cast(毫秒).count();
#如果你有时间
#否则
字符缓冲区[25];//保存“2013-12-01 21:31:42”
if(strftime(缓冲区,25,“%Y”,本地时间(&s))){

现在一旦你获得了当前的日期和时间,基于此,计算明年1月1日午夜的纪元时间应该不会太困难

在计算完一年的预计纪元时间后,向前看,你所要做的就是在做日志记录时将其与当前时间进行比较。如果它还没有达到预先计算的1月1日午夜时间,你就知道一年还没有过去


所以,你根本不需要计算每一个数据包的年。只需要检查当前的时间,而不是预先计算的1月1日午夜时间,除非政治家们决定改变时区,否则这不应该改变,而所有这些都在运行。

< P>首先,你可以考虑<代码> Currut岁月()。<代码> >返回<代码> int <代码>(例如2016),可能与TMYYEX//COD>字段……然后避免制作C++字符串。< /P>
然后,你说的是高数据包速率,所以你可能有一些。你没有解释它是如何完成的(希望你使用一些库,或者至少你自己的循环…),但是你可能在事件循环中每十分之一秒计算一次当前年。或者让其他线程偶尔计算一次当前年(您可能需要一个互斥锁,或者使用
std::atomic
作为当前年份的类型…

Jan
开头的日志条目的年份发生了更改,并且只更改了那些日志条目

日志条目有时会出现顺序错误,或者带有在先前处理过程中保存的时间戳

从PC时钟附加年份将产生不良结果,例如

2016年12月31日23:59:58正常 2016年1月1日00:01:01远程设备放入数据包的打印时间,远程时钟运行有点快 2017年12月31日23:59:59打印时间戳在日志记录发生前两秒本地保存 2017年1月1日00:00:03恢复正常 您不能将本地时钟的年份与日志消息的第二个月连接在一起。您必须指定年份,以避免较大的时钟跳变

由于您正试图生成Unix时间(从纪元算起的秒数),请先将日志消息时间转换为Julian(从年初算起的秒数),然后测试Julian是否小于或大于1000万(大约4个月)。

您可以“缓存”您生成的字符串,并且仅在年份发生变化时才对其进行更改。这可能只是一个“小”改进,取决于哪些操作花费的时间最多

//somewhere
static int currentYear = 0;
static std::string yearStr = ""; 

//in your function
auto now = std::chrono::system_clock::now();   
auto tnow = system_clock::to_time_t(now);
auto lt = localtime(&tnow); //or gmtime depends on your needs.
if(currentYear != lt.tm_year)
{
    yearStr = std::to_string(lt.tm_year + 1900);
    currentYear = t.tm_year;
}

return yearStr;
我不确定静态是否对读取字符串的性能有任何负面/正面的影响,或者由于缓存的局部性,成员变量在这里可能会更好。您必须对此进行测试


如果您在多个线程中使用此选项,您必须在此处使用互斥锁,这可能会降低性能(同样,您必须对此进行测量)你是否已经描述了在那里花费了最多的时间?如果是字符串转换,我可能会有一个想法,但不确定是否需要很多时间。而且模通常是一个昂贵的操作。如果源时间戳不完整,你不能做得很简单。因为你使用C++,所以我删除了你的C标签。(C和C++是不同的语言),并且添加了C++ 11标签,因为你使用的是关键字<代码> Audio< /Cord>和 TooLog[/Case],你能不能从你的包捕获中得到信息?例如,如果你使用的是LIPPCAP,你将得到一个带有包的时间戳的结构(在Stimt TimeValm中),转换为您选择的文本表示形式很简单。(另一方面,如果您正在解析来自例如tcpdump的文本输出,您最好不要这样做,而是使用libpcap,或者找到一种方法来配置syslog服务器以存储适当的时间戳)“除非政客们决定改变你的时区,而所有这些都在运行……”这不是不可想象的,在同一年,闰秒可能会被宣布。事实上,这是相当普遍的。你应该偶尔更新“历元”(我假设UTC)数据包速率平均为500000 pps。“如果”“您建议的声明将被检查?@LightnessRacesinOrbit只有当您的时区为“右/…”时,这才是真的。”时区,计算闰秒。这在实践中非常罕见。普通时区忽略闰秒,ntpd缓慢调整系统时钟的速度,在一天中减慢或加快它,以吸收闰秒。自大纪元以来增加了约30秒的闰秒,如果大纪元时间包括闰秒,则:00-第二个大纪元的时间不会再被60平均整除。但它仍然是。除非你的TZ是“right/America/New_York”,而不是“America/New_York”,例如。@SamVarshavchik:“普通时区忽略闰秒”,它们不会。如果这是真的,本地时区将是UTC的偏移量加上
//somewhere
static int currentYear = 0;
static std::string yearStr = ""; 

//in your function
auto now = std::chrono::system_clock::now();   
auto tnow = system_clock::to_time_t(now);
auto lt = localtime(&tnow); //or gmtime depends on your needs.
if(currentYear != lt.tm_year)
{
    yearStr = std::to_string(lt.tm_year + 1900);
    currentYear = t.tm_year;
}

return yearStr;