Home >
Using UDP socket connections for low-latency and loss-tolerant scenarios in AIR 2 (Part 2)
So now that we understand the usage of UDP lets jump right into building a basic UDP client and server. We'll use the DatagramSocket class to send packets to a specific port at a specific address. We'll also bind our socket to a local port to receive any incoming packets directed at us. In this case we'll be sending packets from an AIR 2 client to a Java server and back over localhost (remote addresses work just the same). Our client application will initiate the communication by saying "Hello, how are you?". Our server will then respond by saying "I'm quite well, thank you".
A quick note about socket security. When dealing with socket connections outside of the application sandbox a cross-domain policy is required. We'll be working inside the application sandbox where we don't have the same constraints, but be aware that some additional work is required when working with other sockets types outside of AIR.
In our AIR application the first thing we want to do is make a new datagramSocket and bind it to an address and a port to receive packets.
private var datagramSocket:DatagramSocket = new DatagramSocket();
protected function creationCompleteHandler(event:FlexEvent) : void {
datagramSocket.bind(4455, "127.0.0.1");
}
By doing this we're binding the socket to port 4455 on 127.0.0.1 (localhost). You'll want to make sure that the port isn't already in use by another application or an else error will occur. For our example I've chosen the arbitrary ports "4455" and "4456" for our client and server to communicate back and forth on. Since client and server are both on the same machine we need to use different port numbers but these numbers can be identical when dealing with two remote systems if you'd like.
At this point we're almost ready to receive any data sent to our application on this port. There is one additional step: to enable on the receiving of data using DatagramSocket.receive(). We want to enable this a little further down the line, so for now lets access the payload. The incoming packet comes in the form of a ByteArray and is accessed through the DatagramSocketDataEvent.DATA event.
datagramSocket.addEventListener(DatagramSocketDataEvent.DATA, dataHandler)
You'll also want to add handling for I/O and Security errors in case something goes wrong. This works the same as it does for the Socket and XMLSocket classes.
private var datagramSocket:DatagramSocket = new DatagramSocket();
protected function creationCompleteHandler(event:FlexEvent) : void {
datagramSocket.addEventListener(DatagramSocketDataEvent.DATA, dataHandler)
datagramSocket.addEventListener(IOErrorEvent.IO_ERROR, IOErrorHandler);
datagramSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
datagramSocket.bind(4455, "127.0.0.1");
}
Naturally once the data comes in we want to do something with it. How you process your data will depend on the data you are sending. In this case we're expecting a UTF-8 encoded string from the server so we can use the ByteArray.readUTFBytes() method to convert our packet to a string and trace its value
private function dataHandler(event:DatagramSocketDataEvent) : void {
trace( event.data.readUTFBytes(event.data.length) );
}
var packet:ByteArray = new ByteArray();
packet.writeUTFBytes("Hello, how are you?");
protected function clickHandler(event:MouseEvent) : void {
var packet:ByteArray = new ByteArray();
packet.writeUTFBytes("Hello, how are you?");
datagramSocket.send(packet, 0, 0, "127.0.0.1", 4455);
datagramSocket.receive()
}
Now that we've sent a packet and we're expecting a response we want to allow that response to be received. You'll notice that datagramSocket.receive() is called immediately after sending our packet so this can happen. Once the response is received and processed its generally best to close the connection unless dealing with a constant stream of data. This can be done using the DatagramSocket.close() method. Once we have our response we're not expecting any more packets so lets close the connection in our data handler.
private function dataHandler(event:DatagramSocketDataEvent) : void {
trace( event.data.readUTFBytes(event.data.length) );
datagramSocket.close();
}
And with that we're set to send and receive data on our UDP socket. In part 3 we'll cover how to write our Java UDP socket server for our client to communicate with
Download client and server source
See part 1 of this series here See part 3 of this series here



Facebook Application Development
Hi,
Could you describe how should we configure our envirnoment ?
Thanks,
Andrew
Can you be more specific? The environment for what?
Well sorry, the question was how to set up an envirnoment for building your examples (flex+java). I was trying to configure FlashDevelop but finally I managed with Flash Builder 4.
So for those who would have similar problems like me here are some small instructions:
I have downloaded latest flex_sdk_4 build (currently it is http://fpdownload.adobe.com/pub/flex/sdk/builds/flex4/flex_sdk_4.0.0.11921.zip) then downloaded latest AIR 2 SDK (http://download.macromedia.com/pub/labs/air/2/b1/air2_b1_sdk_win_111709.zip) and extracted it to the directory of flex_sdk_4 then in Flash Builder 4 go to Window>Preferences, Installed Flex SDKs and give a path to the new SDK. That's it.
For java sources I simply imported them as a new project in Eclipse. and built as a application.
How will be usefull.
Just curious if we could use AIR's datagramsocket class and use it with a flex client instead of air's. Id rather avoid having something someone would have to download.
How would I go about setting up the cross-domain policy?
Hi,
I pasted my code at http://www.pasteyourcode.com/14552 - the problem is, that my DatagramSocket doesn't receive any data.
Thanks for you help, Tobee
Just curious if we could use AIR's datagramsocket class and use it with a flex client instead of air's. Id rather avoid having something someone would have to download.
Mike (Online Measurement Conversions)
Just curious if we could use AIR's datagramsocket class and use it with a flex client instead of air's. Id rather avoid having something someone would have to download.
Mike (Online Measurement Conversions)
Unfortunately no. DatagramSocket is AIR 2 only. There are other socket classes available outside of AIR however if UDP isn't a necessity.