时间服务器时间类型问题

时间:2014-06-26 16:07:11

标签: c linux sockets networking time-t

所以我在Linux上的C语言中写了一点服务器客户端应用程序,它应该将当前的unix时间戳发送给客户端。

它可以正常工作,但我被告知time_t可能并不总是相同的大小和字节顺序。我如何确保发送客户始终了解的时间?

截至目前我只是做

time_t now = htonl(time(0));

并发送。

我搜索了谷歌和stackoverflow,但似乎其他人只发送由ctime()或strftime()生成的时间字符串。

提前致谢!

1 个答案:

答案 0 :(得分:3)

由于在发送方和接收方的解释方式不同,因此一般发送二进制数据容易出错。

特别是对于time_t,它甚至不清楚涉及多少位,它可能是32或64甚至更复杂的东西,因为time_t甚至可能被实现为{ {1}}。

在使用htonl()的特殊情况下,假定为32位,因为struct取32位值。

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

以编程方式,这可能如下所示:

htonl()

要撤销此操作,您可以使用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"


但是,如果你真的想以二进制格式发送自Epoch以来的秒数并保持故障安全和便携性,你需要处理三件事:

  1. 以便携方式获取自Epoch以来的秒数。
  2. 选择一个足够大的整数类型。
  3. 将此“大”值转换为网络字节顺序。
  4. 可能的方法是:

    "2014-05-20 13:14:15"

    关于如何实施非标准#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. */ ,请参阅此问题的各种答案:Big Endian and Little Endian support for byte ordering


    上面示例中的所有代码都假设运行代码的系统提供了一个计时器,但对htonll()的调用不会失败。