Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 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-строки с префиксами
и первую строку я обработал, то как мне ее убрать оттуда?

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

Старый 24.02.2010, 03:45
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 2  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Код AS3:
private function handleTcpData(event:Event):void
{
	var len:uint;
	var str:String;
	var newBA:ByteArray;
 
	if (!_socket.bytesAvailable) return;
	try
	{
		_socket.readBytes(_ba, _ba.bytesAvailable, _socket.bytesAvailable);
 
		// прочитать длину UTF строки
		while (_ba.bytesAvailable >= 2)
		{
			len = _ba.readUnsignedShort();
			if (!len)
			{
				trace("XXX invalid len = " + len);
				_ba.position = 0;
				_ba.length = 0;
				return;
			}
			// теперь прочитать саму UTF строку
			if (_ba.bytesAvailable >= len)
			{
				str = _ba.readUTFBytes(len);
				updateGUI(str);
 
				// скопировать оставшиеся байты (не работает)
				newBA = new ByteArray();
				if (_ba.bytesAvailable)
					newBA.readBytes(_ba, 0, _ba.bytesAvailable);
				_ba = newBA;
			}
			else
			{
				// Ну вот вы и не прочитали неокончившуюся строку, а что теперь?
			}
		}
	}
	catch (e:Error)
	{
		trace('XXX ' + e);
		_ba.position = 0;
		_ba.length = 0;
		return;
	}
}
__________________
Hell is the possibility of sanity

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

Регистрация: May 2006
Адрес: Germany
Сообщений: 74
Нашел ответ, я копировал байты не в ту сторону, надо так:

Код AS1/AS2:
var newBA:ByteArray = new ByteArray();
_ba.readBytes(newBA);
_ba = newBA;
Цитата:
// Ну вот вы и не прочитали неокончившуюся строку, а что теперь?
Не проблема, когда придет остаток строки, handleTcpData() вызовется 2й раз

пока
Алекс

Старый 24.02.2010, 23:14
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 4  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Цитата:
Сообщение от afarber Посмотреть сообщение
Не проблема, когда придет остаток строки, handleTcpData() вызовется 2й раз
Да, но вот только вы уже прочитали к тому времени длину строки, и позиция в вашем "буфере" уже перешла дальше, т.е. вы будете читать первые 2 байта еще раз (а там уже будет начало новой строки вместо ее длины).
__________________
Hell is the possibility of sanity

Старый 24.02.2010, 22:54
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 5  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,787
Не забывайте, что данные могут прийти не полностью за один проход.

Старый 24.02.2010, 23:02
cleptoman вне форума Посмотреть профиль Отправить личное сообщение для cleptoman Найти все сообщения от cleptoman
  № 6  
Ответить с цитированием
cleptoman
 
Аватар для cleptoman

блогер
Регистрация: Mar 2007
Сообщений: 1,291
Записей в блоге: 5
Отправить сообщение для cleptoman с помощью ICQ
а почему могут прийти не полностью?
(вопрос тож актуален)
__________________
http://cleptoman.free-lance.ru
achivements: дважды благословлен на воровство. осеяный благодатью

Старый 24.02.2010, 23:32
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 7  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,787
Цитата:
Сообщение от cleptoman Посмотреть сообщение
а почему могут прийти не полностью?
(вопрос тож актуален)
Есть такая штука, называется «пакеты». Размер оного регламентируется настройками сети и прочими параметрами. Так вот входящий поток будет разбит на эти пакеты.

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

Регистрация: Jul 2008
Адрес: t:2, x: 0.76
Сообщений: 553
Отправить сообщение для mayakwd с помощью ICQ Отправить сообщение для mayakwd с помощью Skype™
потому что сокеты пхп например разрезают информацию в случае заполнения буффера отправки.
__________________
Блог, Twitter
Брюзга.

Создать новую тему Ответ Часовой пояс GMT +4, время: 20:38.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 20:38.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.