Первый вопрос о стеке! Я искал... Обещаю. Я не нашел ответов на свои затруднения. У меня... серьезно обостряющаяся проблема, если не сказать больше. Короче говоря, я разрабатываю инфраструктуру для игры, в которой мобильные приложения (приложение для Android и приложение для iOS) взаимодействуют с сервером, используя сокеты для отправки данных в базу данных. Сценарий внутреннего сервера (который я называю BES или Back End Server) состоит из нескольких тысяч строк кода. По сути, у него есть основной метод, который принимает входящие подключения к сокету и разветвляет их, и метод, который считывает ввод из сокета и определяет, что с ним делать. Большая часть кода находится в методах, которые отправляют и получают данные из базы данных и отправляют их обратно в мобильные приложения. Все они работают нормально, кроме самого нового метода, который я добавил. Этот метод извлекает большой объем данных из базы данных, кодирует их как объект JSON и отправляет обратно в мобильное приложение, которое также декодирует их из объекта JSON и выполняет необходимые действия. Моя проблема в том, что эти данные очень большие, и большую часть времени они не проходят через сокет за одну запись данных. Таким образом, я добавил одну дополнительную запись данных в сокет, которая информирует приложение о размере объекта JSON, которое оно собирается получить. Однако после этой записи следующая запись отправляет пустые данные в мобильное приложение.
Странно то, что когда я удаляю эту первую запись, которая отправляет размер объекта JSON, фактическая отправка объекта JSON работает нормально. Это просто очень ненадежно, и я должен надеяться, что он отправляет все это за одно чтение. Чтобы добавить больше странности в ситуацию, когда я делаю размер данных, которые вторая запись отправляет огромным числом, приложение iOS будет читать его правильно, но у него будут данные в середине пустого массива.
Что происходит в мире? Любое понимание очень ценится! Ниже приведен лишь базовый фрагмент двух моих команд записи на стороне сервера.
Имейте в виду, что ВЕЗДЕ в этом сценарии чтение и запись работают нормально, но это единственное место, где я выполняю 2 операции записи подряд.
Сценарий сервера находится на сервере Ubuntu на собственном языке C с использованием сокетов Berkeley, а iOS использует класс-оболочку AsyncSocket.
int n;
//outputMessage contains a string that tells the mobile app how long the next message
//(returnData) will be
n = write(sock, outputMessage, sizeof(outputMessage));
if(n < 0)
//error handling is here
//returnData is a JSON encoded string (well, char[] to be exact, this is native-C)
n = write(sock, returnData, sizeof(returnData));
if(n < 0)
//error handling is here
Мобильное приложение выполняет два вызова чтения и получает outputMessage
просто отлично, но returnData
всегда представляет собой набор пустых данных, если только я не перезапишу sizeof(returnData)
каким-то очень большим числом, и в этом случае iOS получит данные в середине в противном случае пустой объект данных (точнее, объект NSData). Также может быть важно отметить, что метод, который я использую на стороне iOS в моем классе AsyncSocket, считывает данные до длины, которую он получает от первого вызова записи. Поэтому, если я скажу ему прочитать, скажем, 10000 байт, он создаст объект NSData такого размера и будет использовать его в качестве буфера при чтении из сокета.
Любая помощь очень, БОЛЬШЕ оценена. Заранее спасибо всем!
iovec
и использованияwritev
вместоwrite
. Вы правы в том, что это на самом деле НЕ писало что-то пустое. Результат возвратаwrite
всегда был правильным количеством байтов. Единственный способ, которым я мог заставить клиента увидеть, что он читает ЛЮБЫЕ данные, состоял в том, чтобы сделать буфер ОГРОМНЫМ, в который клиент помещал считанные данные, и каким-то образом, буквально в середине этого буфера, были данные. Это было странно. Но теперь я читаю его, пока он не получит нулевой терминатор и не отправит его через сокет какiovec
. - person shaunpickford   schedule 14.04.2011