|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: Mar 2011
Сообщений: 16
|
Проблема с UDP обменом между сервером и AIR приложением
Доброго времени суток!
У меня возникла следующая проблема. В локальной сети есть сервер, с которого через UDP передаются некоторые числовые данные. Мне необходимо эти данные принять и обработать в своем AIR приложении. Для прослушивания UDP сервера использую класс DatagramSocket, который позволяет отправлять и получать пакеты UDP. Тут возникает пролема, которую я решить не могу. Мое приложение просто выполняется и совершенно ничего не приоисходит. Я нуб в ActionScript, и прошу совета знающих людей. Код выглядит следующим образом. package source { import flash.display.Sprite; import flash.events.Event; import flash.net.DatagramSocket; import flash.events.DatagramSocketDataEvent; public class ExampleDatagramSocket extends Sprite { private var udpSocket:DatagramSocket; public function ExampleDatagramSocket() { trace ("Constructor complete"); } private function bind(event:Event):void { if (udpSocket.bound) { udpSocket.close(); udpSocket = new DatagramSocket; } udpSocket.bind(8989, "127.0.0.1"); //Связываем сокет с указанным локальным адресом и портом. udpSocket.addEventListener(DatagramSocketDataEvent.DATA, readDataRecieved); udpSocket.receive(); //Активируем этот объект DatagramSocket, чтобы получить входящие пакеты на связанный IP-адрес и порт. } private function connect(event:Event):void { udpSocket.connect("192.1.130.190", 50000); //Подключаем сокет к указанному удаленному адресу и порту. } private function readDataRecieved(event:DatagramSocketDataEvent):void { if (udpSocket.connected) { trace ("Recieved from" + event.srcAddress + ":" + event.srcPort + "> " + event.data.readUTFBytes( event.data.bytesAvailable )); //если сокет установил соединение с указанным сервером, то выводим данные, которые тот посылает } else { trace ("Remote Server Unavailable"); // иначе выводим, что сервер недоступен } } } } |
|
|||||
listener
|
Непонятна логика работы вашенго класса. И почему биндимся на локалхост?
Разберитесь до конца с примером из хэлпа: package { import flash.display.Sprite; import flash.events.DatagramSocketDataEvent; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.net.DatagramSocket; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFieldType; import flash.utils.ByteArray; import flash.utils.Timer; public class DatagramSocketExample extends Sprite { private var datagramSocket:DatagramSocket = new DatagramSocket();; private var localIP:TextField; private var localPort:TextField; private var logField:TextField; private var targetIP:TextField; private var targetPort:TextField; private var message:TextField; public function DatagramSocketExample() { setupUI(); } private function bind( event:Event ):void { if( datagramSocket.bound ) { datagramSocket.close(); datagramSocket = new DatagramSocket(); } datagramSocket.bind( parseInt( localPort.text ), localIP.text ); datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, dataReceived ); datagramSocket.receive(); log( "Bound to: " + datagramSocket.localAddress + ":" + datagramSocket.localPort ); } private function dataReceived( event:DatagramSocketDataEvent ):void { //Read the data from the datagram log("Received from " + event.srcAddress + ":" + event.srcPort + "> " + event.data.readUTFBytes( event.data.bytesAvailable ) ); } private function send( event:Event ):void { //Create a message in a ByteArray var data:ByteArray = new ByteArray(); data.writeUTFBytes( message.text ); //Send a datagram to the target try { datagramSocket.send( data, 0, 0, targetIP.text, parseInt( targetPort.text )); log( "Sent message to " + targetIP.text + ":" + targetPort.text ); } catch ( error:Error ) { log( error.message ); } } private function log( text:String ):void { logField.appendText( text + "\n" ); logField.scrollV = logField.maxScrollV; trace( text ); } private function setupUI():void { targetIP = createTextField( 10, 10, "Target IP:", "192.168.0.1" ); targetPort = createTextField( 10, 35, "Target port:", "8989" ); message = createTextField( 10, 60, "Message:", "Lucy can't drink milk." ); localIP = createTextField( 10, 85, "Local IP", "0.0.0.0"); localPort = createTextField( 10, 110, "Local port:", "0" ); createTextButton( 250, 135, "Bind", bind ); createTextButton( 300, 135, "Send", send ); logField = createTextField( 10, 160, "Log:", "", false, 200 ) this.stage.nativeWindow.activate(); } private function createTextField( x:int, y:int, label:String, defaultValue:String = '', editable:Boolean = true, height:int = 20 ):TextField { var labelField:TextField = new TextField(); labelField.text = label; labelField.type = TextFieldType.DYNAMIC; labelField.width = 180; labelField.x = x; labelField.y = y; var input:TextField = new TextField(); input.text = defaultValue; input.type = TextFieldType.INPUT; input.border = editable; input.selectable = editable; input.width = 280; input.height = height; input.x = x + labelField.width; input.y = y; this.addChild( labelField ); this.addChild( input ); return input; } private function createTextButton( x:int, y:int, label:String, clickHandler:Function ):TextField { var button:TextField = new TextField(); button.htmlText = "<u><b>" + label + "</b></u>"; button.type = TextFieldType.DYNAMIC; button.selectable = false; button.width = 180; button.x = x; button.y = y; button.addEventListener( MouseEvent.CLICK, clickHandler ); this.addChild( button ); return button; } } } Последний раз редактировалось alexcon314; 08.04.2011 в 09:04. |
|
|||||
Регистрация: Mar 2011
Сообщений: 16
|
Я понимаю логику работы программы так. Есть два компьютера. Один удаленный, он отсылает в сеть UDP пакеты. Второй - локальный. На локальном компьютере находится AIR приложение, которое по задумке должно принимать пакеты, обрабатывать их и выводить результаты.
Исходя из этого, программа выглядит следующим образом. Создаем объект DatagramSocket, далее подключаемся с помощью метода connect() к удаленному компьютеру (IP="192.1.130.190", Port=50000), отсылающему в сеть пакеты. Далее с помощью метода bind() связываем DatagramSocket с локальным адресом и портом (IP="127.0.0.1", PORT=8989). Я так понял, что локальный адрес - это localhost. Ставим слушатель событий, который следит за тем, приходят ли пакеты на связанный локальный адрес. Если пакеты приходят, то выполняется функция readUDPSocketData, которая по идее должна трейсить, что такие-то данные получены с такого-то адреса и порта. В конце-концов пишем recieve() для активации объекта DatagramSocket, чтобы тот смог получать пакеты на связанный IP-адрес и порт. Я так понимаю, в моей логике где-то содержится epic fail. Укажите на него пожалуйста. P.S. С примером их хелпа разбирался, но тот не работает, выводит ошибку #1009. Но красивости, всякие окошки и поля ввода мне сейчас неинтересны, хочется чтобы просто данные передавались. |
|
|||||
listener
|
1. Удаленный компьютер вещает пакеты в сеть безадресно? Как организована его работа?
2. Локальный компьютер имеет свой IP-адрес? На него и надо делать бинд, ну, или просто bind(), без параметров. Бинд на локалхост означает, что будут приниматься только пакеты от локальных же приложений. 3. Пример из хелпа вполне рабочий. Более того, он позволяет проверить работу DatagramSocket, даже не имея удаленного компьютера. В этом случае как раз достаточно забиндиться на 127.0.0.1:[port] и слать пакеты на этот же адрес - 127.0.0.1:[port]. У меня под FlashDevelop пример собрался и заработал на раз-два. 4. Где в вашем примере вызываются bind() и connect() вообще не понятно. "красивости", которые вам не интересны, в примере из хелпа - это кнопки и поля ввода? Как раз события от кнопок и запускают тут bind() и connect() и позволяют потестить работу DatagramSocket. Чем они вам не угодили - не ясно. 5. Еще раз повторю: разберитесь с примером доконца. Последний раз редактировалось alexcon314; 08.04.2011 в 13:08. |
|
|||||
Регистрация: Mar 2011
Сообщений: 16
|
Спасибо за ответ, попытаюсь разобраться, просто под Flash Professional этот пример ни за что собираться не хочет.
|
|
|||||
а если не подписываться на ошибки сокета? он про них умолчит или выдаст ?
|
|
|||||
Регистрация: Mar 2011
Сообщений: 16
|
Добрый день! Я разобрался в хелпе, данные сейчас передаются, но возникла очередная загвоздка. UDP сервер, находящийся по адресу 192.1.130.178:55556, отсылает в сеть пакеты на адрес 192.1.130.178:55555. В качестве UDP сервера используется стандартный блок сетевого обмена UDP пакета MATLAB&Simulink. Числовые данные, приходя в мое AIR приложение, превращаются в ничего не говорящие мне символы в виде квадратов. Выглядит это следующим образом.
[SWF] recieve.swf - 2970 байт после декомпрессии Received from 192.1.130.178:55556> Received from 192.1.130.178:55556> Received from 192.1.130.178:55556> Received from 192.1.130.178:55556> Received from 192.1.130.178:55556> Received from 192.1.130.178:55556> Received from 192.1.130.178:55556> Received from 192.1.130.178:55556> символ Received from 192.1.130.178:55556> символ Received from 192.1.130.178:55556> символ Received from 192.1.130.178:55556> символ Received from 192.1.130.178:55556> символ Received from 192.1.130.178:55556> символ Received from 192.1.130.178:55556> символ Код программы здесь. package source { import flash.display.Sprite; import flash.events.DatagramSocketDataEvent; import flash.events.Event; import flash.net.DatagramSocket; import flash.utils.ByteArray; public class DatagramSocketExample extends Sprite { private var datagramSocket:DatagramSocket; //The IP and port for this computer private var localIP:String = "192.1.130.178"; private var localPort:int = 55555; //The IP and port for the target computer private var targetIP:String = "192.1.130.178"; private var targetPort:int = 55556; public function DatagramSocketExample() { datagramSocket = new DatagramSocket(); datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, dataReceived ); //Bind the socket to the local network interface and port datagramSocket.bind( localPort, localIP ); //Listen for incoming datagrams datagramSocket.receive(); } public function dataReceived( event:DatagramSocketDataEvent ):void { //Read the data from the datagram trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " + event.data.readUTFBytes(event.data.bytesAvailable)); } } } |
|
|||||
если попробовать Socket или XMLSocket ?
и что там за протокол у матлаба ? |
|
|||||
Регистрация: Mar 2011
Сообщений: 16
|
Матлаб имеет стандартный UDP протокол, и все числовые транзакции осуществляются именно через него, поэтому Socket и XMLSocket не подходят к сожалению...
|
|
|||||
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
под протоколом в данном случае подразумевается более высокий уровень. какие данные и в каком виде шлёт матлаб по UDP? скорей всего это какой-то бинарный протокол, который нужно отдельно парсить.
__________________
Отряд Котовскага |
Часовой пояс GMT +4, время: 12:50. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|