Показать сообщение отдельно
Старый 24.02.2010, 03:10
afarber вне форума Посмотреть профиль Отправить личное сообщение для afarber Посетить домашнюю страницу afarber Найти все сообщения от afarber
  № 1  
Ответить с цитированием
afarber
 
Аватар для afarber

Регистрация: May 2006
Адрес: Germany
Сообщений: 74
Question Считывать из сокета в ByteArray

Привет,

мой мувик считывает через сокет от сервера (на Перле)
сначала длину UTF строки как unsigned short и потом саму эту строку.

Сначала я пытался делать просто:

Код AS1/AS2:
_socket = new Socket();
_socket.addEventListener(ProgressEvent.SOCKET_DATA, handleTcpData);
 
private function handleTcpData(event:Event):void {
  while (_socket.bytesAvailable) {
     var str:String = _socket.readUTF();
     updateGUI(str);
  }
}
но этот код часто зависает у пользователей которые далеко от моего сервера.

Я поискал решения в интернете и похоже что единственный
надежный способ - это читать _socket.bytesAvailable байтов
в отдельный ByteArray и когда видишь, что там достаточно
данных, вычитывать их оттуда нужными методами
(типа readUTF, readShort, readObject и т.д.).

И вот мой новый код:

Код AS1/AS2:
private function handleTcpData(event:Event):void {
       var len:uint;
 
       if (0 == _socket.bytesAvailable)
               return;
 
       try {
               _socket.readBytes(_ba, _ba.bytesAvailable, _socket.bytesAvailable);
 
               // прочитать длину UTF строки
               while (_ba.bytesAvailable >= 2) {
                       len = _ba.readUnsignedShort();
 
                       if (0 == len) {
                               trace('XXX invalid len = ' + len);
                               _ba.position = 0;
                               _ba.length = 0;
                               return;
                       }
 
                       // теперь прочитать саму UTF строку
                       if (_ba.bytesAvailable >= len) {
                               var str:String = _ba.readUTFBytes(len);
                               updateGUI(str);
 
                               // скопировать оставшиеся байты (не работает)
                               var newBA:ByteArray = new ByteArray();
                               newBA.readBytes(_ba);
                               _ba = newBA;
                       }
               }
       } catch(e:Error) {
               trace('XXX ' + e);
               _ba.position = 0;
               _ba.length = 0;
               return;
       }
}
К сожалению этот код не работает когда через сокет
приходят например сразу 2 строки с префиксами.

Я добавил пару trace() и вижу что не работает мой код,
в котором я пытаюсь убрать из ByteArray те байты,
которые я уже обработал:

Код AS1/AS2:
                               // скопировать оставшиеся байты (не работает)
                               var newBA:ByteArray = new ByteArray();
                               // здесь newBA.length почему-то 0
                               newBA.readBytes(_ba);
                               _ba = newBA;
Подскажите как мне исправить?

Т.е.: если в ByteArray две UTF-строки с префиксами
и первую строку я обработал, то как мне ее убрать оттуда?

Спасибо
Алекс