SERVICES

BLOGS

ARTICLES, TUTORIALS AND HOW-TOS

PROJECTS AND PORTFOLIO

LINK DIRECTORY

OUTSIDE LINKS

A simple echo server that serves socket policy files

Later versions of Flash 9 and Flash 10 have much tightened security features that make it  ***EXTREMELY***  frustrating for beginners to get the hang of when doing sockets programming in Actionscript 3 for the first time. The real problem lies not with the Flash socket APIs which are actually quite easy to figure out, but more on coding a server that properly passes the security hurdles.

Below is a very straightforward and simple implementation of a Flash/Actionscript 3 compatible echo server in Python that has been tested to work with versions all the way up to Flash Player 10.0.22.87.

This multi-threaded server will correctly serve the required socket policy file on the same port that you connect to, eliminating the annoyance of having to run a separate policy file server on port 843.

One nice feature of this server is that, on echo, it will also show you the number of connection threads spawned so far by the server as well as the number of threads currently in use.

#!/usr/bin/env python

import socket,thread

class Polserv(object):
  def __init__(self):
    self.numthreads = 0
    self.tidcount   = 0
    self.port       = 8888
    self.sock       = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # The socket options above are so you don't have to wait around
    # to bind() to a port for which an earlier socket was bind()-ed
    # to, but is still waiting to be completely destroyed.
    self.sock.bind(('', self.port))
    self.sock.listen(5)

  def run(self):
    while True:
      thread.start_new_thread(self.handle, self.sock.accept())
      # start_new_thread() will block on accept() and will only
      # spawn a new thread when a new incoming connection is accept()-ed

  def handle(self,conn,addr):
    self.numthreads += 1
    self.tidcount   += 1
    tid=self.tidcount

    while True:
      data=conn.recv(2048)
      if not data:
        conn.close()
        self.numthreads-=1
        break
      if "<policy-file-request/>\0" in data:
        conn.sendall("""
          <?xml version="1.0"?>
          <cross-domain-policy>
            <allow-access-from domain="*" to-ports="*"/>
          </cross-domain-policy>""")
        conn.close()
        self.numthreads-=1
        break
      conn.sendall("[#%d (%d running)] %s" % (tid,self.numthreads,data) )

Polserv().run()
# A shortcut. Create a Polserv object by calling its constructor, then
# run it immediately without assigning to a variable (e.g. anonymously)

On a Linux/Unix system, you can run this in the background and ensure that exiting the shell does not terminate it by using nohup

# nohup ./server.py &

Related