Сетевое приложение работает в симуляторе, но не на iPhone

0

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

//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, а не localhost в вашем приложении.
  • 0
    Просто мысль: это может быть проблемой utf8? Я имею в виду, ваше имя пользователя на самом деле «имя пользователя» или это что-то написано на норвежском языке?
Показать ещё 3 комментария
Теги:
iphone
tcp

1 ответ

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
    Но это потребовало бы от меня переписать основную часть моих сетевых модулей. Ну да ладно, спасибо в любом случае :)
  • 0
    В качестве временного исправления, чтобы увидеть, была ли проблема на самом деле в битовом поле, я убрал флаги длины для всех полей в структурах, как на стороне сервера, так и на стороне клиента. Это сделало все целые 32 битными, и это, очевидно, приводит к некоторому ненужному трафику в «\ 0» битах, но теперь сервер хорошо общается с клиентом, и «имя пользователя» фактически читается как «имя пользователя». Спасибо @DavidH за указание в правильном направлении :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню