网络应用程序可在模拟器中运行,但不适用于iPhone

时间:2013-11-29 22:42:51

标签: c++ ios iphone objective-c tcp

我目前正在为iPhone编写游戏,它通过TCP / IP与C ++服务器通信,以交换用户数据,朋友列表,声音文件等。在socket上读/写时,服务器和客户端使用相同的结构:

//Packet used for small stuff
typedef struct small_packet {
    int msgtype:8;
    int size:16;
    int extra:16;
    int following:24;
    char data1[64];
    char data2[64];
} packet;

//Packet used for files
typedef struct file_packet {
    int msgtype:8; //For partial file packet this should be 0x02
    int size:16;
    int extra:16;
    int following:24;
    char data1[64];
    char fileBuffer[1024];
} filePacket;

//Used for file headers
typedef struct filehead_packet {
    int msgtype:8;
    int size:16;
    int extra:16;
    int following:24;
    char data1[64];
    int fileid;
    char rest[60];
} fileheadPacket;

在模拟器模式下,该应用程序可以正常工作,并通过互联网与服务器通信。然而,当在iPhone上运行时,它也不起作用。登录数据包使用小数据包(上部结构)。 msgtype为0x01,大小为sizeof(数据包),以下为0,extra为0,data1保存用户名,data2保存计算出的密码哈希值。服务器似乎获得0x01,因为它将传入消息视为登录请求。它也变大了。从data1和data2复制用户名和密码哈希时出现问题。

当cout在服务器上时,服务器似乎没有读取用户名的前三个字母。当我尝试使用say" username"登录时,服务器得到" rname&#34 ;,并且PWHash具有类似的偏移量(3 * sizeof(char))。这只发生在我在实际单元上运行应用程序时,而不是在模拟器中运行。

我承认我最近修改了结构的布局 - 到目前为止,额外字段只有8位,并且在后续字段后面还有一个额外的int:8字段。我已经在客户端和服务器上使用此信息更新了结构,并在两者上运行了clean + rebuild,所以我不明白为什么它会很重要。事实上,8 + 8 = 16,这是额外字段的新大小,因此data1和data2字段应该在内存中与旧结构相同的偏移量开始。

对此有任何帮助将不胜感激!我非常坚持这一点,并且真的很烦人,不知道什么是错的...它可能是我所知道的所有字母(iPhone是字性的,不是吗?),但如果是这样的话,我不知道服务器如何将0x01解释为0x01 ......哦。提前谢谢!

1 个答案:

答案 0 :(得分:1)

我建议记录所有结构的sizeof - 包装可能是不同的mac / ios。如果是这样,clang可能有一些指令来完全像mac一样打包结构。此外,最好使用宏将所有数字转换为网络顺序(参见ntoh宏)。

更多的问题是你使用位域是非常不可移植的,理论上可能会随着编译器的更新而改变。我建议为发送器和接收器使用一组不同的“传输”结构,使用其中的uint64_t值作为标志:

typedef struct small_packet {
    uint64_t flags;
    char data1[64];
    char data2[64];
} packet;

您可以编写非常简单的C代码,将“真实”结构映射到用于传输的结构。 K& R C警告不要在平台上使用位域(我只是查了一下: - ))。