其他分享
首页 > 其他分享> > c-时间服务器时间类型问题

c-时间服务器时间类型问题

作者:互联网

因此,我在linux上用C编写了一些时间服务器-客户端应用程序,该应用程序应该将当前的unix时间戳发送给客户端.

一切正常,但是我被告知time_t的大小和字节顺序可能并不总是相同.如何确定我发送给客户的时间总是可以理解的?

截至目前,我只是做

time_t now = htonl(time(0));

并发送.

我在google和stackoverflow上搜索,但似乎其他所有人都只是发送ctime()或strftime()生成的时间字符串.

提前致谢!

解决方法:

由于发送方和接收方采用不同的解释方式,一般发送二进制数据容易出错.

特别是对于time_t,甚至还不清楚会涉及多少位,它可能是32位或64位,甚至更复杂,因为time_t甚至可能实现为结构.

在使用htonl()的特殊情况下,假设32位,因为htonl()接受32位值.

因此,故障安全解决方案的确是发送系统时间的文本表示.

以编程方式,这可能看起来像这样:

char st[64] = "";

{
  struct * tm = gmtime(time(NULL));
  if (NULL == tm)
  {
    fprintf(stderr, "gmtime() failed\n");
  }
  {
    if(0 == strftime(st, sizeof(st), "%s", tm)) /* Prints the text representaiotn of the seconds since Epoch into st. */
    {
      fprintf(stderr, "strftime() failed\n");
    }
  }
}

要反转此操作,可以使用strptime():

char st[64] = "123456789123";
time_t t;
memset(&t, 0, sizeof(t));
{
  struct tm = {0};
  char p = strptime(t, "%s", &tm);
  if (NULL == p || p != (t + strlen(t)))
  {
    fprintf(stderr, "strptime() failed\n");
  }
  else
  {
    t = mktime(&tm);
  }
}

使用strptime()和strftime()的好处是,您只需更改调用这两个函数时指定的格式,就可以轻松更改传输中日期/时间的格式.

将“%s”更改为“%Y-%m-%d%H:%M:%S”会转移时间,例如“ 2014-05-20 13:14:15”.

但是,如果您真的想以二进制格式发送自Epoch以来的秒数并保持故障安全和可移植性,则需要注意三件事:

>以可移植的方式获取距大纪元以来的秒数.
>选择绝对足够大的整数类型.
>将此“大”值转换为网络字节顺序.

一个可能的方法是:

#include <time.h>
#include <inttypes.h> /* For uint64_t, as 64bit should do to represent the seconds since Epoch for the next few years. */

...

time_t t_epochbegin;
memset(&t_epochbegin, 0, sizeof(t_epochbegin);
uint64_t t_host = (uint64_t) difftime(time(NULL), t_epochbegin); /* Get the seconds since Epoch without relying on time_t being an integer. */
uint64_t t_network = htonll(t_host); /* Convert to network byte order. */

有关如何实现非标准htonll()的信息,请参见以下问题的各种答案:Big Endian and Little Endian support for byte ordering

上面示例中的所有代码均假定运行代码的系统提供了计时器,尽管对time()的调用不会失败.

标签:time-t,sockets,networking,c-3,linux
来源: https://codeday.me/bug/20191121/2052798.html