我有一个客户端和服务器程序,我想从客户端发送整个结构,然后在服务器上输出结构成员“ID”。
我已完成所有连接等,并已设法通过以下方式发送字符串:
send(socket, string, string_size, 0);
那么,是否可以通过send()发送结构而不是字符串?我可以将服务器上的缓冲区替换为相同类型的空结构吗?
答案 0 :(得分:4)
客户端和服务器机器“是否相同”?你提出的建议只有在每一端的C编译器在内存中的结构完全相同时才有效。有很多原因可能不是这种情况。例如,客户端和服务器宏可能具有不同的体系结构,那么它们在内存中表示数字的方式(big-endian,little-endian)可能会有所不同。即使客户机器和服务器机器具有相同的体系结构,两个不同的C编译器可能对它们如何在存储器中布置结构具有不同的策略(例如,字段之间的填充以在字边界上对齐整数)。即使是具有不同标志的相同的 conmpiler也可能会产生不同的结果。
实际上,我猜你的客户端和服务器是同一种机器,所以你提出的是可行的,但是你需要注意,作为一般规则,它不会,这就是为什么标准,如发明了CORBA,或者为什么人们使用一些通用的表示,比如XML。
答案 1 :(得分:2)
如果客户端和服务器以完全相同的方式布局结构,则可以使用相同的填充来表示字段大小相同。例如,如果你的结构中有long
,那么一台机器上可能是32位,另一台机器上可能是64位,在这种情况下,结构将无法正确接收。
在您的情况下,如果客户端和服务器总是在非常相似的C实现上(例如,如果这只是您用于学习一些基本概念的代码,或者由于某些其他原因您知道您的代码只需要在你当前版本的OSX上运行),那么你可以侥幸逃脱它。请记住,您的代码不一定能在其他平台上正常运行,并且在适用于大多数实际情况之前还有更多工作要做。
对于大多数客户端 - 服务器应用程序,这意味着答案是您不能一般地执行此操作。您实际做的是根据发送的字节数,顺序,含义等来定义消息。然后在每一端,您执行特定于平台的操作,以确保您使用的结构具有完全所需的布局。即便如此,如果您要发送struct little-endian的整数成员,那么您可能必须进行一些字节交换,然后您希望您的代码在big-endian机器上运行。存在数据交换格式,如XML,json和Google的协议缓冲区,因此您无需执行此类繁琐工作。
[编辑:还记得当然有些结构成员永远无法通过网络发送。例如,如果你的结构中有一个指针,那么地址指的是发送机器上的内存,并且在接收端没用。抱歉,如果这对你来说已经很明显了,但当他们刚刚开始使用C时,对于每个人来说当然不是很明显。
答案 2 :(得分:1)
如果你正确地做这件事,那么通过网络发送结构很难。
Carl是对的 - 你可以通过网络发送一个结构:
send(socket, (char*)my_struct, sizeof(my_struct), 0);
但事情就是这样:
因此,人们经常提出的解决方案是使用一个序列化结构的例程。也就是说,它一次向结构发送一个数据成员,确保客户端和服务器只发送()和recv()您编入程序的确切指定字节数。
答案 3 :(得分:1)
你可以,但你需要了解两件重要的事情。
答案 4 :(得分:0)
是的,相同类型的结构都具有相同的大小。如果你的指针投射正确,你就可以去了。
答案 5 :(得分:0)
一般来说,这样做是个坏主意,即使你的客户端和你的服务器都以同样的方式在内存中布局结构。
即使您不打算来回传递更复杂的数据结构(包括指针),我建议您在通过网络发送数据之前对其进行序列化。
答案 6 :(得分:-3)
将数据作为文本文件发送,然后在收到后对其进行解码。如果您希望将数据作为发送数据,这是最好的方式!