c++ - c/c++ - 通过套接字发送 time_t 的最安全方式

标签 c++ c time network-programming

我已经设置了一个 C++ 服务器/客户端环境,并试图从服务器向客户端发送一个 time_t 值(这在任何服务器中都是有用的)。但是我遇到了一个令人头疼的问题:time_t 似乎不符合任何大小规范。我想知道通过网络发送 time_t 的最安全(更便携)的方法是什么。

这是一个小例子:

time_t T = time(NULL);
unsigned char * P = (unsigned char *)&T;
// ... Convert it to network byte order, etc.

// Here, 's' would be the socket, and 'S'
// the size of the data that is going to
// be sent
send(s, P, S, 0);

我有两个问题:

  • time_t 的大小不固定
  • time_t 可以是有符号或无符号整数数据类型的 typedef

我如何处理这两个问题,以便我可以在(几乎)任何架构之间安全地发送它?

提前致谢。

编辑:在看到相同的三个答案后,我发现最好在此处回复。对不起,我之前没有澄清。我更喜欢以“纯”字节发送它,尽管将它作为字符串发送不是问题。据我了解,我需要(再次)记住主机系统中 time_t 数据类型的签名和大小,不是吗? (感谢和抱歉)

最佳答案

首先,我认为您需要决定是否要处理 C 标准使 time_t 的含义过于模糊的问题(它不一定以秒为单位,甚至没有任何有意义的数字属性,如顺序/比较)。这与每个 现有和历史实现的行为相反,其中time_t 以秒为单位。 C 和 POSIX 也允许 time_t 是浮点类型;据我所知,没有实现使用它,并且在 POSIX 上它会相当有害,因为 time_tvalue 必须是整数,就像它在struct timespec

如果您认为 time_t 始终是自纪元以来的整数秒数,即 对于系统之间的交换有意义,那么它只是格式化它们的问题。最安全的做法是简单地转换为一个整数类型,该整数类型足够大以存储任何有意义的值,并且在所有系统上大小相同:即 int64_t。然后使用您用于序列化 int64_t 的任何正常方式,以不受字节序差异影响。

如果另一方面你想“绝对”便携,你应该为“纪元”(标准纪元或你自己选择的纪元)计算你自己的 time_t 值,然后使用 difftime 转换为表示“自纪元以来的秒数”的 double 值,并将 double 格式化为 snprintf(buf, sizeof buf, "%.0f",差异)。请注意,在可移植 C 中计算纪元的 time_t 值实际上非常困难,因为大多数标准函数都在本地时间工作,而您需要通用时间。您可以使用 gmtimemktimelocaltime 函数来解决这个问题,但这并不简单...

关于c++ - c/c++ - 通过套接字发送 time_t 的最安全方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13957254/

相关文章:

c++ - 枚举 "ghost values": what for?

c - C 中的二项式系数

c - vfork() 系统调用中的返回值

c - #define vs 嵌入式环境中的枚举(它们如何编译?)

c++ - 在函数调用中使用类型 vector<pair<int,int>>::iterator&

c++ - 未初始化的值由堆分配 : Unordered_map 创建

android - 格式化从 ExifInterface.TAG_DATETIME 获取的时间和日期

ios - 如何在午夜不触发 applicationSignificantTimeChange

Go time.Parse() 得到 “month out of range” 错误

c++ - 数组的名称是右值吗?