Разбор сегмента данных из потока TCP - PullRequest
0 голосов
/ 13 декабря 2011

У меня возникли проблемы с получением пакетных данных из потока 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 - массив. в конце это те же данные, на которые ссылаются

Ответы [ 2 ]

2 голосов
/ 13 декабря 2011

Используйте следующую логику:

1) Достаточно ли у вас байтов для определения длины?Если нет, получите еще несколько байтов и повторите попытку.

2) Достаточно ли у вас байтов, чтобы иметь один полный блок?Если нет, получите еще несколько байтов и повторите попытку.

3) Извлеките одну полную единицу, используя декодированную длину из шага 1, и обработайте ее.

4) Если у нас нет оставшихся байтов, мыготово.

5) Вернитесь к шагу 1 для обработки оставшихся байтов.

0 голосов
/ 13 декабря 2011

хорошо, поэтому я получил некоторую помощь от ( этой группы ), которую вы не сможете увидеть без входа в группу. в любом случае есть 3-х байтовый заголовок. так что мой len, который равен 6, а не 1280, как я думал, на самом деле равен 9, как только 3 добавлено для заголовка. и это возвращает мне значение, которое я искал для (9), поскольку сегмент данных составляет 9 байт.

Спасибо за предложения, Дэвид, за хорошие базовые знания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...