-2

我开发了一个小型(非常小的)ftp 客户端和服务器。只有当它们使用相同的拱门时
,这两个程序才能编译和运行良好。

  1. 如果客户端是 Ubuntu amd64 而服务器是 Ubuntu i386 我有一个段错误(我认为这是一个指针问题)
  2. 如果客户端是 Ubuntu amd64 而服务器是 Ubuntu amd64 一切正常
  3. 如果客户端是 Ubuntu i386 而服务器是 Ubuntu i386 一切正常

我怎样才能让这两个程序在不同的拱门上工作?
是代码问题吗?如果是这样,我该怎么办?
提前致谢!

4

1 回答 1

5

这可能是各种类型的大小不同,您正在通过网络发送和接收它们。由于大小不匹配,协议将变得不同步。

Linux 使用x86_64的LP64 数据模型int,因此仍然是 32 位,但是long64 位。在 x86long上是 32 位。

stdint.h幸运的是,C 标准在头文件中定义了几种固定宽度的整数类型。如果包含,则可以使用无符号类型和有符号类型,其中n为 8、16、32 或 64。网络协议要考虑的另一件事是字节顺序。POSIX 提供函数、、和,它们分别将 32 位和 16 位整数从主机顺序转换为网络顺序,反之亦然。uintn_tintn_thtonlhtonsntohlntohs

编辑:

正如可变长度编码器所指出的,发送整个结构也是不可移植的(尽管它在 x86 和 x86_64 之间)。如果您通过网络发送一个结构,您应该一次一个成员地发送它,并分配到接收端的适当字段中。

编辑2:

size_t也不是可移植的数据类型。您应该选择适合协议的明确大小的类型。大概uint32_t是个不错的选择。

另外,由于所有的大小修饰符printf都是基于标准的short//类型intlong你需要使用宏<inttypes.h>来制作格式字符串。例如:

#include <inttypes.h>

/* ... */

int32_t signed32;
uint16_t unsigned16;

printf("Signed 32 is %"PRIu32" and unsigned 16 is %"PRId16"\n", signed32, unsigned16);

您的系统可能在这些头文件上有手册页(我的 fedora 系统有),因此您可以在命令提示符下使用

man stdint.h

man inttypes.h

获取有关这些标头中定义的类型、宏和函数的更多信息。

于 2012-07-03T20:26:31.437 回答