C/C ++-通过套接字发送time_t的最安全方法 [英] c/c++ - safest way to send time_t over socket
问题描述
我已经建立了一个C ++服务器/客户端环境,并试图将time_t值从服务器发送到客户端(在任何服务器中都是有用的).但是我很头疼:time_t似乎不在任何大小规格范围内.我想知道通过网络发送time_t的最安全(更可移植)的方法是什么.
I've set up a C++ server/client environment, and am trying to send a time_t value from the server to the client (an useful thing in any server). But I'm coming accross a headache: time_t seems to not be under any size specifications. I'm wondering what is the safest (more portable) way to send time_t over the network.
这是一个小例子:
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
如何处理这两个问题,以便可以在(几乎)任何体系结构之间安全地发送它?
How can I handle that two issues so that I can send it safely between (almost) any architecture?
谢谢.
看到相同的三个答案后,我发现最好在这里做出答复.抱歉,我之前没有对此进行澄清.我更喜欢以纯"字节发送它,尽管以字符串形式发送它不是问题.据我了解,我需要再次牢记主机系统中time_t数据类型的签名和大小,不是吗? (谢谢,抱歉)
After seeing the same three answers, I find it better to response here. I'm sorry I did not clarify that before. I prefer sending it in 'pure' bytes, although sending it as a string is not a problem. As far as I understand, I would need to keep in mind (again) the signedness and the size of time_t data type in the host system, isn't it? (thanks and sorry)
推荐答案
首先,我认为您需要确定是否要处理C标准使time_t
的含义过于含糊的问题(不一定)以秒为单位表示,甚至没有任何有意义的数值属性(例如订单/比较).这与每个现有和历史实施的行为相反,其中time_t
以秒为单位. C和POSIX都允许time_t
为浮点类型;据我所知,没有实现可以利用它,而在POSIX上这将是相当有害的,因为time_t
的 value 必须是它在struct timespec
中使用的方式的整数,依此类推
First, I think you need to decide if you want to deal with the issue that the C standard leaves the meaning of time_t
overly vague (it's not necessarily represented in seconds and doesn't even have any meaningful numerical properties like order/comparison). This is contrary to the behavior of every existing and historical implementation, where time_t
is in seconds. Both C and POSIX also allow time_t
to be a floating point type; as far as I know, no implementations make use of this, and on POSIX it would be rather harmful since the value of time_t
has to be an integer the way it's used in struct timespec
, etc.
如果您认为自纪元以来time_t
始终是整数秒数,即 values 对于系统之间的交换有意义,则感到满意,那么只需格式化它们即可.最安全的做法是简单地将其强制转换为一个整数类型,该类型足够大以存储任何有意义的值,并且在所有系统上的大小都相同:int64_t
.然后使用不影响字节序差异的正常方式使用int64_t
进行序列化.
If you decide you're happy assuming time_t
is always an integral number of seconds since the epoch, i.e. the values are meaningful for interchange between systems, then it's just a matter of formatting them. The safest thing to do would be to simply cast to a integer type that's large enough to store any meaningful value and that's the same size on all systems: that would be int64_t
. Then use whatever normal means you use for serializing int64_t
in a way that's immune to endian differences.
另一方面,如果您希望绝对"便携,则应为"epoch"(标准的或您自己选择的epoch)计算自己的time_t
值,然后使用difftime
转换为代表距纪元后的秒数"的双精度,并用snprintf(buf, sizeof buf, "%.0f", diff)
格式化double
.请注意,在便携式C中为时期计算time_t
值实际上是非常困难的,因为大多数标准函数都在本地时间工作,而您则需要通用时间.您可以使用gmtime
,mktime
和localtime
函数来解决这些问题,但这并不容易...
If on the other hand you want to be "absolutely" portable, you should compute your own time_t
value for "the epoch" (either the standard one or your own choice of epoch), then use difftime
to convert to a double representing "seconds since the epoch", and format the double
with snprintf(buf, sizeof buf, "%.0f", diff)
. Note that computing a time_t
value for the epoch in portable C is actually quite difficult because most of the standard functions work in local time, whereas you need universal time. There are tricks you can do with the gmtime
, mktime
, and localtime
functions to figure it out, but it's nontrivial...
这篇关于C/C ++-通过套接字发送time_t的最安全方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!