У меня возникли проблемы с получением пакетных данных из потока TCP. Я думаю, что это отчасти связано с непониманием ответов серверов.
мой код (цель c):
unsigned type=0;
unsigned bufferFirstByte=0;
unsigned bufferSecondByte=0;
unsigned bufferThirdByte=0;
NSScanner *hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:0]];
[hexToInt scanHexInt:&bufferFirstByte];
hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:1]];
[hexToInt scanHexInt:&bufferSecondByte];
hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:2]];
[hexToInt scanHexInt:&bufferThirdByte];
hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:0]];
[hexToInt scanHexInt:&type];
int len = (bufferSecondByte<<8)+bufferSecondByte;
if (![mutableBuffer count]<(3+len)) {
NSArray *payload = [mutableBuffer subarrayWithRange:NSMakeRange(2,([mutableBuffer count] - 2))];
NSLog(@"length %d",len);
[self processReceive:type length:len payload:payload];
}
- это то, что смоделировано из этого кода JavaScript:
self.receive = function (itemName, data) {
self.log("Receiving: " + self.toHex(data));
self.ourData += data;
while (self.ourData.length >= 3) {
var type = self.ourData.charCodeAt(0);
var len = (self.ourData.charCodeAt(1) << 8) + self.ourData.charCodeAt(2);
if (self.ourData.length < (3 + len)) { // sanity check: buffer doesn't contain all the data advertised in the packet
break;
}
var payload = self.ourData.substr(3,len);
self.ourData = self.ourData.substr(3 + len);
self.processMessage(type, len, payload); // process payload
}
};
Причина моделирования заключается в том, что проект команды fusion javascript взаимодействует с тем же сервером, которым я являюсь (контроллером crestron).
Однако я никогда не мог заставить лен работать, и я думаю, что это вызывает мою проблему. При просмотре примера пакета (05: 00: 06: 00: 00: 03: 00: 52: 00) длина len будет равна 1280 (см. Выше математика), даже если часть данных составляет всего 9 байтов.
В настоящее время мой код будет работать, но в нем отсутствуют определенные данные. Это происходит из-за потоковой передачи, которую выполняет TCP (некоторые пакеты объединены, а другие фрагментированы). Но, не зная размера сегмента данных, я не могу решить проблему и считаю, что ответом является переменная len
. Но я не вижу, как это правильно реализовать.
Мой вопрос сводится к этому. Как я могу определить размер сегмента данных из этой переменной len
или управлять моим методом приема, чтобы исключать только один сегмент данных за раз (что из моего исследования невозможно, так как TCP сделан как поток)?
У меня такое чувство, что будут вопросы, поэтому я попытаюсь ответить на некоторые из них здесь.
A. Как вы придумали 1280: посмотрите на математику в методе ((self.ourData.charCodeAt(1) << 8) + self.ourData.charCodeAt(2);)
(5 << 8) + 0 = 1280d </p>
B. Почему вы используете разные индексы:
Вы заметите, что индекс для каких данных идет куда (payload, len, type
). Это просто потому, что они имеют свои полезные данные / байты данных в виде строки, а myn - массив. в конце это те же данные, на которые ссылаются