[英]Network app works in simulator, but not on the iPhone
我目前正在為iPhone編寫游戲,該游戲通過TCP / IP與C ++服務器通信,以交換用戶數據,朋友列表,聲音文件等。 在套接字上讀寫時,服務器和客戶端使用相同的結構:
//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;
在模擬器模式下,該應用程序可以完美運行,並可以通過Internet與服務器通信。 但是,當在iPhone上運行時,它也無法正常運行。 登錄數據包使用小數據包(上層結構)。 msgtype為0x01,大小為sizeof(packet),其后為0,extra為0,data1保存用戶名,data2保存計算出的密碼哈希值。 似乎服務器將收到的消息視為登錄請求,因此獲得了0x01。 它也得到大小。 從data1和data2復制用戶名和密碼哈希時,出現問題。
在服務器上執行提示操作時,服務器似乎未讀取用戶名的前三個字母。 當我嘗試使用“用戶名”登錄時,服務器獲取“ rname”,並且PWHash具有類似的偏移量(3 * sizeof(char))。 這僅在我在實際設備上而不是在模擬器上運行應用程序時發生。
我承認我最近修改了結構的布局-到目前為止,Extra字段只有8位,而后一個字段之后還有一個int:8字段。 我已經在客戶端和服務器上使用此信息更新了結構,並在兩者上運行了clean + rebuild,所以我不明白為什么這么重要。 事實上,8 + 8 = 16是額外字段的新大小,因此data1和data2字段應在內存中的偏移量與舊結構相同。
任何幫助,將不勝感激! 我對此非常執着,根本不知道出什么問題真是令人討厭。。。據我所知,這可能是字節序(iPhone是字節性的,不是嗎?),但是如果是這樣,我不知道該怎么辦服務器將0x01解釋為0x01 ...哦。 提前致謝!
我建議為所有結構記錄一個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警告不要在平台之間使用位域(我只是在查找它:-)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.