2013-11-29 6 views
0

В настоящее время я пишу игру для iPhone, которая связывается с сервером C++ через TCP/IP для обмена пользовательскими данными, списками друзей, звуковыми файлами и т. Д. Сервер и клиент используют одни и те же структуры при чтении/записи на сокете:Сетевое приложение работает в симуляторе, но не на iPhone.

//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'ing на сервере, кажется, первые три буквы имени пользователя не прочитаны сервером. Когда я пытаюсь войти с именем «username», сервер получает «rname», а PWHash имеет аналогичное смещение (3 * sizeof (char)). Это происходит только при запуске приложения на самом устройстве, а не в симуляторе.

Я признаю, что недавно я изменил компоновку структур - до сих пор дополнительное поле имело только 8 бит, и после следующего поля у меня было дополнительное int: 8. Я обновил структуры с этой информацией как на клиенте, так и на сервере, и запустил чистую + перестройку для обоих, поэтому я не понимаю, почему это имеет значение. И по сути, 8 + 8 = 16, который является новым размером дополнительного поля, поэтому поля data1 и data2 должны начинаться с того же смещения в памяти, что и для старых структур.

Любая помощь с этим была бы принята с благодарностью! Я очень зациклен на этом, и это действительно раздражает, не зная, что вообще не так. Это может быть утверждение для всего, что я знаю (iPhone байтабельный, не так ли?), Но если это так, я понятия не имею, как сервер интерпретирует 0x01 как 0x01 ... ну хорошо. Заранее спасибо!

+0

Сервер является фактическим удаленным сервером, как я понимаю, не так ли? Потому что если это «localhost», вам нужно использовать «IP» локального хоста, а не использовать «localhost» в вашем приложении. – Neeku

+0

Просто мысль: может быть проблема utf8? Я имею в виду ваше имя пользователя на самом деле «имя пользователя» или это что-то написано на норвежском языке? – gWiz

+0

Сервер удален, и у меня есть полный адрес ipv4, жестко закодированный в моем приложении. @gWiz: мое имя пользователя состоит только из простых букв из английского алфавита. По сути, клиент только принимает имена пользователей в [a ... z]. –

ответ

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 предупреждает против использования битовых полей на разных платформах (я просто посмотрел вверх :-)).

+0

Но это потребует от меня переписать большую часть моих модулей net-com. Ну ладно, спасибо в любом случае :) –

+0

Как временное исправление, чтобы увидеть, была ли проблема на самом деле битполе, я удалил флаги длины для всех полей в структурах, как на стороне сервера, так и на стороне клиента. Это заставило все int 32-битные длины, и это, очевидно, приводит к некоторому ненужному трафику '\ 0'-бит, но теперь сервер хорошо взаимодействует с клиентом, а «имя пользователя» фактически читается как «имя пользователя». Спасибо @DavidH за то, что указали мне в правильном направлении :) –

Смежные вопросы