[ENet-discuss] Python interface to ENET

Lee Salzman lsalzman at telerama.com
Mon Nov 3 06:58:30 PST 2003


I added your autoconf stuff to the distribution. Muchos gracias. Could
you help me out with an "install" option for the Makefile, though? :)

But, could you write some documentation on how to use your new pyenet
wrapper before I include it in? 

I am probably going to gear up for a 1.0 release soon. Things that I
think need to be done first, though:

1) make install
2) new pyenet docs
3) finish the stubs for making enet thread safe (might save this for
after, though)

Any other suggestions from you folks out there?

Lee

On Sat, Nov 01, 2003 at 06:13:12AM -0800, Scott Robinson wrote:
> I've been using the pyenet layer for a couple days now and I've been working
> through wrinkle after wrinkle. Ling, thanks for your excellent work, but I
> found it was just easier to create a new Pyrex interface... :-(
> 
> My new interface has all the functionality of the pyenet layer and then some
> - it also has improved error checking and it doesn't seem to mysteriously
> drop connection at certain times...
> 
> Attached to this e-mail is a source tree patch in unified form with the
> following:
> 
> New enet.pyx, updated test scripts, and commented out build options to
> return to the original pyenet.
> 
> New automake/autoconf build scripts for enet.
> 
> Is this too much?
> 
> Scott.
> 
> -- 
> http://quadhome.com/            - Personal webpage
> http://tranzoa.net/             - Corporate webpage
> 
> -----BEGIN GEEK CODE BLOCK-----
> Version: 3.12
> GAT dpu s: a--- C++ UL+++ P++ L+++ E- W++ N++ o+ K++ w++ 
> O M V(-) PS+ PE Y+ PGP+++ t@ 5 X- R- tv(-) b++++ DI++++ D+ 
> G e* h! r* y 
> ------END GEEK CODE BLOCK------

> diff -urdN enet-old/Makefile enet/Makefile
> --- enet-old/Makefile	2003-10-30 07:55:31.000000000 -0800
> +++ enet/Makefile	1969-12-31 16:00:00.000000000 -0800
> @@ -1,32 +0,0 @@
> -CC=gcc
> -COPTFLAGS=-Wall -pedantic -O3 -fomit-frame-pointer
> -
> -# Linux
> -CFLAGS=$(COPTFLAGS) -Iinclude -DHAS_GETHOSTBYNAME_R -DHAS_GETHOSTBYADDR_R -DHAS_POLL -DHAS_FCNTL -DHAS_MSGHDR_FLAGS
> -# FreeBSD, etc.
> -# CFLAGS=$(COPTFLAGS) -Iinclude -DHAS_POLL -DHAS_FCNTL -DHAS_MSGHDR_FLAGS
> -# Solaris
> -# CFLAGS=$(COPTFLAGS) -Iinclude -DHAS_GETHOSTBYNAME_R -DHAS_GETHOSTBYADDR_R -DHAS_FCNTL
> -
> -OBJS= \
> -	host.o \
> -	list.o \
> -	memory.o \
> -	packet.o \
> -	peer.o \
> -	protocol.o \
> -	unix.o \
> -	win32.o
> -
> -default: all
> -
> -all: libenet.a
> -
> -clean:
> -	-rm -f libenet.a $(OBJS)
> -
> -libenet.a: $(OBJS)
> -	ar ruv libenet.a $(OBJS)
> -	ranlib libenet.a
> -
> -
> diff -urdN enet-old/Makefile.am enet/Makefile.am
> --- enet-old/Makefile.am	1969-12-31 16:00:00.000000000 -0800
> +++ enet/Makefile.am	2003-11-01 04:05:02.000000000 -0800
> @@ -0,0 +1,3 @@
> +lib_LIBRARIES = libenet.a
> +libenet_a_SOURCES = host.c list.c memory.c packet.c peer.c protocol.c unix.c win32.c
> +INCLUDES = -Iinclude/
> diff -urdN enet-old/README enet/README
> --- enet-old/README	2003-07-23 20:34:16.000000000 -0700
> +++ enet/README	2003-11-01 04:35:21.000000000 -0800
> @@ -1,8 +1,16 @@
>  Please visit the ENet homepage at http://enet.cubik.org for installation
>  and usage instructions.
>  
> -ENet is currently in severe need of a decent build system. Any contributions
> -to this effect are extremely welcome.
> +If you obtained this package from CVS, the quick description on how to build
> +is:
> +
> +# Generate the build system.
> +
> +aclocal && automake -a --foreign && autoconf
> +
> +# Compile and install the library.
> +
> +./configure && make && make install
>  
>  See pyenet/readme.txt for further information on Ling Lo's Python wrapper for
>  ENet.
> diff -urdN enet-old/configure.in enet/configure.in
> --- enet-old/configure.in	1969-12-31 16:00:00.000000000 -0800
> +++ enet/configure.in	2003-11-01 04:23:00.000000000 -0800
> @@ -0,0 +1,13 @@
> +AC_INIT(libenet, 0.1)
> +AM_INIT_AUTOMAKE(libenet.a, 0.1)
> +
> +AC_PROG_CC
> +AC_PROG_RANLIB
> +
> +AC_CHECK_FUNC(gethostbyaddr_r, [AC_DEFINE(HAS_GETHOSTBYADDR_R)])
> +AC_CHECK_FUNC(poll, [AC_DEFINE(HAS_POLL)])
> +AC_CHECK_FUNC(fcntl, [AC_DEFINE(HAS_FCNTL)])
> +
> +AC_CHECK_MEMBER(struct msghdr.msg_flags, [AC_DEFINE(HAS_MSGHDR_FLAGS)], , [#include <sys/socket.h>])
> +
> +AC_OUTPUT([Makefile])
> diff -urdN enet-old/pyenet/enet.pyx enet/pyenet/enet.pyx
> --- enet-old/pyenet/enet.pyx	1969-12-31 16:00:00.000000000 -0800
> +++ enet/pyenet/enet.pyx	2003-11-01 03:11:01.000000000 -0800
> @@ -0,0 +1,504 @@
> +# enet.pyx
> +#
> +# DESCRIPTION
> +#
> +#   Python ENET Wrapper implemented in pyrexc.
> +#
> +# RATIONALE
> +#
> +#   Ling Lo's pyenet.c module had a problem with dropping a connection after
> +#   a short amount of time. Having seen other Python <-> C interfaces
> +#   defined in pyrexc, I decided it probably has a much better time of
> +#   surviving time.
> +#
> +#   Hopefully no one will be too mad with the option of choice?
> +#
> +# LICENSE
> +#
> +#   Copyright (C) 2003, Scott Robinson (scott at tranzoa.com)
> +#
> +#   Redistribution and use in source and binary forms, with or without
> +#   modification, are permitted provided that the following conditions are
> +#   met:
> +#
> +#   Redistributions of source code must retain the above copyright notice,
> +#   this list of conditions and the following disclaimer.
> +#
> +#   Redistributions in binary form must reproduce the above copyright
> +#   notice, this list of conditions and the following disclaimer in the
> +#   documentation and/or other materials provided with the distribution.
> +#
> +#   The names of its contributors may not be used to endorse or promote
> +#   products derived from this software without specific prior written
> +#   permission.
> +#
> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
> +#   IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
> +#   TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> +#   PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
> +#   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> +#   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> +#   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
> +#   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
> +#   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
> +#   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> +#   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +#
> +# CHANGELOG
> +#
> +#   Sat Nov  1 00:36:02 PST 2003  Scott Robinson <scott at tranzoa.com>
> +#     Began developing test interface after a day of coding...
> +#
> +
> +
> +import  atexit
> +
> +# SECTION
> +#   C declarations and definitions for the interface.
> +
> +cdef extern from "Python.h" :
> +  char *  PyString_AsString           (object string)
> +  int     PyString_Size               (object string)
> +  object  PyBuffer_FromMemory         (void *ptr, int size)
> +  object  PyString_FromStringAndSize  (char *v, int len)
> +
> +cdef extern from "enet/types.h" :
> +  ctypedef unsigned char  enet_uint8
> +  ctypedef unsigned short enet_uint16
> +  ctypedef unsigned int   enet_uint32
> +  ctypedef unsigned int   size_t
> +
> +cdef extern from "enet/enet.h" :
> +  cdef enum :
> +    ENET_HOST_ANY = 0
> +
> +  ctypedef struct ENetAddress :
> +    enet_uint32   host
> +    enet_uint16   port
> +
> +  ctypedef enum ENetPacketFlag :
> +    ENET_PACKET_FLAG_RELIABLE = (1 << 0)
> +
> +  ctypedef struct ENetPacket :
> +    size_t        referenceCount
> +    enet_uint32   flags
> +    enet_uint8   *data
> +    size_t        dataLength
> +
> +  ctypedef enum ENetPeerState :
> +    ENET_PEER_STATE_DISCONNECTED                = 0
> +    ENET_PEER_STATE_CONNECTING                  = 1
> +    ENET_PEER_STATE_CONNECTED                   = 2
> +    ENET_PEER_STATE_DISCONNECTING               = 3
> +    ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECTION = 4
> +    ENET_PEER_STATE_ZOMBIE                      = 5
> +
> +  ctypedef struct ENetPeer :
> +    ENetAddress   address
> +    ENetPeerState state
> +    enet_uint32   packetLoss
> +    enet_uint32   packetThrottleAcceleration
> +    enet_uint32   packetThrottleDeceleration
> +    enet_uint32   packetThrottleInterval
> +    enet_uint32   roundTripTime
> +
> +  ctypedef struct ENetHost
> +
> +  ctypedef enum ENetEventType :
> +    ENET_EVENT_TYPE_NONE       = 0
> +    ENET_EVENT_TYPE_CONNECT    = 1
> +    ENET_EVENT_TYPE_DISCONNECT = 2
> +    ENET_EVENT_TYPE_RECEIVE    = 3
> +
> +  ctypedef struct ENetEvent :
> +    ENetEventType   type
> +    ENetPeer       *peer
> +    enet_uint8      channelID
> +    ENetPacket     *packet
> +
> +  int   enet_initialize     ()
> +  void  enet_deinitialize   ()
> +
> +  int enet_address_set_host (ENetAddress *address, char *hostName)
> +  int enet_address_get_host (ENetAddress *address, char *hostName, size_t nameLength)
> +
> +  ENetPacket *  enet_packet_create    (void *dataContents, size_t dataLength, enet_uint32 flags)
> +  void          enet_packet_destroy   (ENetPacket *packet)
> +  int           enet_packet_resize    (ENetPacket *packet, size_t dataLength)
> +
> +  ENetHost *  enet_host_create              (ENetAddress *address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
> +  void        enet_host_destroy             (ENetHost *host)
> +  ENetPeer *  enet_host_connect             (ENetHost *host, ENetAddress *address, size_t channelCount)
> +  int         enet_host_service             (ENetHost *host, ENetEvent *event, enet_uint32 timeout)
> +  void        enet_host_flush               (ENetHost *host)
> +  void        enet_host_broadcast           (ENetHost *host, enet_uint8 channelID, ENetPacket *packet)
> +  void        enet_host_bandwidth_limit     (ENetHost *host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
> +
> +  int             enet_peer_send                  (ENetPeer *peer, enet_uint8 channelID, ENetPacket *packet)
> +  ENetPacket *    enet_peer_receive               (ENetPeer *peer, enet_uint8 channelID)
> +  void            enet_peer_ping                  (ENetPeer *peer)
> +  void            enet_peer_reset                 (ENetPeer *peer)
> +  void            enet_peer_disconnect            (ENetPeer *peer)
> +  void            enet_peer_throttle_configure    (ENetPeer *peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deacceleration)
> +
> +# SECTION
> +#   Enumerations and constants.
> +
> +HOST_ANY              = ENET_HOST_ANY
> +
> +PACKET_FLAG_RELIABLE  = ENET_PACKET_FLAG_RELIABLE
> +
> +PEER_STATE_DISCONNECT                   = ENET_PEER_STATE_DISCONNECTED
> +PEER_STATE_CONNECTING                   = ENET_PEER_STATE_CONNECTING
> +PEER_STATE_CONNECTED                    = ENET_PEER_STATE_CONNECTED
> +PEER_STATE_DISCONNECTING                = ENET_PEER_STATE_DISCONNECTING
> +PEER_STATE_ACKNOWLEDGING_DISCONNECTION  = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECTION
> +PEER_STATE_ZOMBIE                       = ENET_PEER_STATE_ZOMBIE
> +
> +EVENT_TYPE_NONE       = ENET_EVENT_TYPE_NONE
> +EVENT_TYPE_CONNECT    = ENET_EVENT_TYPE_CONNECT
> +EVENT_TYPE_DISCONNECT = ENET_EVENT_TYPE_DISCONNECT
> +EVENT_TYPE_RECEIVE    = ENET_EVENT_TYPE_RECEIVE
> +
> +# SECTION
> +#   Python exposed class definitions.
> +
> +cdef class Address :
> +  cdef ENetAddress    _enet_address
> +
> +  def __init__ (self, address, port) :
> +    """__init__ (str address, int port)
> +
> +    Performs a resolution upon the given address. If 'address' is None, HOST_ANY is assumed."""
> +
> +    self.host = address
> +    self.port = port
> +
> +  def __getattr__ (self, name) :
> +    if name == "host" :
> +      if self._enet_address.host :
> +        maxhostname = 200
> +        host = PyString_FromStringAndSize (NULL, maxhostname)
> +
> +        if enet_address_get_host (&self._enet_address, host, maxhostname) :
> +          raise IOError ("Resolution failure!")
> +
> +        return host
> +      elif self._enet_address.host == ENET_HOST_ANY :
> +        return "*"
> +    elif name == "port" :
> +      return self._enet_address.port
> +    else :
> +      return AttributeError ("Address object has no attribute '" + name + "'")
> +
> +  def __setattr__ (self, name, value) :
> +    if name == "host" :
> +      if not value or value == "*":
> +        self._enet_address.host = ENET_HOST_ANY
> +      else :
> +        if enet_address_set_host (&self._enet_address, value) :
> +          raise IOError ("Resolution failure!")
> +    elif name == "port" :
> +      self._enet_address.port = value
> +    else :
> +      return AttributeError ("Address object has no attribute '" + name + "'")
> +
> +  def __str__ (self) :
> +      return "%s:%u" % (self.host, self.port)
> +
> +cdef class Packet :
> +  cdef ENetPacket  *_enet_packet
> +
> +  def __init__ (self, dataContents = None, flags = 0) :
> +    """__init__ ([dataContents, int flags])
> +
> +    Creates a packet that may be sent to a peer."""
> +
> +    cdef void    *packet_data
> +    cdef size_t   packet_length
> +
> +    if dataContents or flags :
> +      packet_data = PyString_AsString (dataContents)
> +      packet_length = PyString_Size (dataContents)
> +
> +      self._enet_packet = enet_packet_create (packet_data, packet_length, flags)
> +
> +      if not self._enet_packet :
> +        raise MemoryError ("Unable to create packet structure!")
> +
> +  def __dealloc__ (self) :
> +    """__dealloc__ ()
> +
> +    Destroys the packet and deallocates its data."""
> +
> +    if self._enet_packet and not self._enet_packet.referenceCount :
> +      # WARNING: referenceCount is an internal structure. Is there a better way of doing this?
> +      enet_packet_destroy (self._enet_packet)
> +
> +  def __getattr__ (self, name) :
> +    if self._enet_packet :
> +      if name == "flags" :
> +        return self._enet_packet.flags
> +      elif name == "data" :
> +        # TODO: Find out why the PyBuffer interface is cutting off data!
> +        #return PyBuffer_FromMemory (self._enet_packet.data, self._enet_packet.dataLength)
> +        return PyString_FromStringAndSize (<char *> self._enet_packet.data, self._enet_packet.dataLength)
> +      elif name == "dataLength" :
> +        raise AttributeError ("Access of attribute '" + name + "' on Packet object unimplemented!")
> +      else :
> +        raise AttributeError ("Packet object has no attribute '" + name + "'")
> +    else :
> +      raise MemoryError ("Empty Packet object accessed!")
> +
> +cdef class Peer :
> +  cdef ENetPeer  *_enet_peer
> +
> +  def send (self, channelID, Packet packet) :
> +    """send (int channelID, Packet packet)
> +
> +    Queues a packet to be sent."""
> +
> +    if self._enet_peer and packet._enet_packet :
> +      return enet_peer_send (self._enet_peer, channelID, packet._enet_packet)
> +
> +  def receive (self, channelID) :
> +    """receive (int channelID)
> +
> +    Attempts to dequeue any incoming queued packet."""
> +
> +    if self._enet_peer :
> +      packet = Packet ()
> +      (<Packet> packet)._enet_packet = enet_peer_receive (self._enet_peer, channelID)
> +
> +      if packet._enet_packet :
> +        return packet
> +      else :
> +        return None
> +
> +  def reset (self) :
> +    """reset ()
> +
> +    Forcefully disconnects a peer."""
> +
> +    if self._enet_peer :
> +      enet_peer_reset (self._enet_peer)
> +
> +  def ping (self) :
> +    """ping ()
> +
> +    Sends a ping request to a peer."""
> +
> +    if self._enet_peer :
> +      enet_peer_ping (self._enet_peer)
> +
> +  def disconnect (self) :
> +    """disconnect ()
> +
> +    Request a disconnection from a peer."""
> +
> +    if self._enet_peer :
> +      enet_peer_disconnect (self._enet_peer)
> +
> +  def __getattr__ (self, name) :
> +    if self._enet_peer :
> +      if name == "address" :
> +        address = Address (0, 0)
> +        (<Address> address)._enet_address = self._enet_peer.address
> +
> +        return address
> +      elif name == "state" :
> +        return self._enet_peer.state
> +      elif name == "packetLoss" :
> +        return self._enet_peer.packetLoss
> +      elif name == "packetThrottleInterval" :
> +        return self._enet_peer.packetThrottleInterval
> +      elif name == "packetThrottleAcceleration" :
> +        return self._enet_peer.packetThrottleAcceleration
> +      elif name == "packetThrottleDeceleration" :
> +        return self._enet_peer.packetThrottleDeceleration
> +      elif name == "roundTripTime" :
> +        return self._enet_peer.roundTripTime
> +      else :
> +        raise AttributeError ("Peer object has no attribute '" + name + "'")
> +    else :
> +      raise MemoryError ("Empty Peer object accessed!")
> +
> +  def __setattr__ (self, name, value) :
> +    if self._enet_peer :
> +      if name == "packetThrottleInterval" : 
> +        enet_peer_throttle_configure (self._enet_peer, value, self._enet_peer.packetThrottleAcceleration, self._enet_peer.packetThrottleDeceleration)
> +      elif name == "packetThrottleAcceleration" :
> +        enet_peer_throttle_configure (self._enet_peer, self._enet_peer.packetThrottleInterval, value, self._enet_peer.packetThrottleDeceleration)
> +      elif name == "packetThrottleDeceleration" :
> +        enet_peer_throttle_configure (self._enet_peer, self._enet_peer.packetThrottleInterval, self._enet_peer.packetThrottleAcceleration, value)
> +      else :
> +        raise AttributeError ("Peer object has no attribute '" + name + "'")
> +    else :
> +      raise MemoryError ("Empty Peer object accessed!")
> +
> +cdef class Event :
> +  cdef ENetEvent  _enet_event
> +
> +  def __getattr__ (self, name) :
> +    if name == "type" :
> +      return self._enet_event.type
> +    elif name == "peer" :
> +      peer = Peer ()
> +      (<Peer> peer)._enet_peer = self._enet_event.peer
> +
> +      return peer
> +    elif name == "channelID" :
> +      return self._enet_event.channelID
> +    elif name == "packet" :
> +      packet = Packet ()
> +      (<Packet> packet)._enet_packet = self._enet_event.packet
> +
> +      return packet
> +    else :
> +      raise AttributeError ("Event object has no attribute '" + name + "'")
> +
> +  def __setattr__ (self, name, value) :
> +    if name == "type" or name == "peer" or name == "channelID" or name == "packet" : 
> +      raise AttributeError ("Attribute '" + name +"' on Event object is read-only.")
> +    else :
> +      raise AttributeError ("Event object has no attribute '" + name + "'")
> +
> +cdef class Host :
> +  cdef ENetHost    *_enet_host
> +  cdef enet_uint32  _enet_incomingBandwidth
> +  cdef enet_uint32  _enet_outgoingBandwidth
> +
> +  def __init__ (self, Address address = None, peerCount = 0, incomingBandwidth = 0, outgoingBandwidth = 0) :
> +    """__init__ (Address address, int peerCount, int incomingBandwidth, int outgoingBandwidth)
> +
> +    Creates a host for communicating to peers. If the address is None, then the host will be a client only."""
> +
> +    (self._enet_incomingBandwidth, self._enet_outgoingBandwidth) = (incomingBandwidth, outgoingBandwidth)
> +
> +    if address :
> +      self._enet_host = enet_host_create (&address._enet_address, peerCount, incomingBandwidth, outgoingBandwidth)
> +    else :
> +      self._enet_host = enet_host_create (NULL, peerCount, incomingBandwidth, outgoingBandwidth)
> +
> +    if not self._enet_host :
> +      raise MemoryError ("Unable to create host structure!")
> +
> +  def __dealloc__ (self) :
> +    """___destroy___ ()
> +
> +    Destroys the host and all resources associated with it."""
> +
> +    if self._enet_host :
> +      enet_host_destroy (self._enet_host)
> +
> +  def connect (self, Address address, channelCount) :
> +    """Peer connect (Address address, int channelCount)
> +
> +    Initiates a connection to a foreign host."""
> +
> +    if self._enet_host :
> +      peer = Peer ()
> +      (<Peer> peer)._enet_peer = enet_host_connect (self._enet_host, &address._enet_address, channelCount)
> +
> +      if not (<Peer> peer)._enet_peer :
> +        raise IOError ("Connection failure!")
> +
> +      return peer
> +
> +  def service (self, timeout) :
> +    """Event service (int timeout)
> +
> +    Waits for events on the host specified and shuttles packets between the host and its peers."""
> +
> +    if self._enet_host :
> +      event = Event ()
> +      result = enet_host_service (self._enet_host, &(<Event> event)._enet_event, timeout)
> +
> +      if result < 0 :
> +        raise IOError ("Servicing error - probably disconnected.")
> +      else :
> +        return event
> +
> +  def flush (self) :
> +    """flush ()
> +
> +    Sends any queued packets on the host specified to its designated peers."""
> +
> +    if self._enet_host :
> +      enet_host_flush (self._enet_host)
> +
> +  def broadcast (self, channelID, Packet packet) :
> +    """broadcast (int channelID, Packet packet)
> +
> +    Queues a packet to be sent to all peers associated with the host."""
> +
> +    if self._enet_host and packet._enet_packet :
> +      enet_host_broadcast (self._enet_host, channelID, packet._enet_packet)
> +
> +  def __getattr__ (self, name) :
> +    if name == "incomingBandwidth" :
> +      return self._enet_incomingBandwidth
> +    elif name == "outgoingBandwidth" :
> +      return self._enet_outgoingBandwidth
> +    else :
> +      raise AttributeError ("Host object has no attribute '" + name + "'")
> +
> +  def __setattr__ (self, name, value) :
> +    if name == "incomingBandwidth" :
> +      self._enet_incomingBandwidth = value
> +      enet_host_bandwidth_limit (self._enet_host, self._enet_incomingBandwidth, self._enet_outgoingBandwidth)
> +    elif name == "outgoingBandwidth" :
> +      self._enet_outgoingBandwidth = value
> +      enet_host_bandwidth_limit (self._enet_host, self._enet_incomingBandwidth, self._enet_outgoingBandwidth)
> +    else :
> +      raise AttributeError ("Host object has no attribute '" + name + "'")
> +
> +# SECTION
> +#   Ensure ENET is properly initialized and de-initialized.
> +
> +def enet_atexit () :
> +  enet_deinitialize ()
> +
> +enet_initialize ()
> +atexit.register (enet_atexit)
> +
> +# SECTION
> +#   Testing
> +
> +def check (host) :
> +  event = host.service (0)
> +
> +  if event.type == EVENT_TYPE_NONE :
> +    pass
> +  elif event.type == EVENT_TYPE_CONNECT :
> +    print "%s connected to %s via %s." % (host, event.peer.address, event.peer)
> +  elif event.type == EVENT_TYPE_DISCONNECT :
> +    print "%s disconnected from %s via %s." % (host, event.peer.address, event.peer)
> +  elif event.type == EVENT_TYPE_RECEIVE :
> +    print "%s received %s containing '%s' from %s via %s." % (host, event.packet, event.packet.data, event.peer.address, event.peer)
> +  else :
> +    print "%s received invalid event %s of type %u." % (host, event, event.type)
> +
> +def test () :
> +  print "Starting services..."
> +
> +  host1 = Host (None, 1, 0, 0)
> +  host2 = Host (Address ("localhost", 6666), 1, 0, 0)
> +
> +  print "Connecting %s (client) to %s (server)..." % (host1, host2)
> +
> +  peer1 = host1.connect (Address ("localhost", 6666), 1)
> +
> +  print "Entering service loop..."
> +
> +  count = 0
> +
> +  while 1 :
> +    check (host1)
> +    check (host2)
> +
> +    count = count + 1
> +
> +    if not (count % 10000) :
> +      print "Sending broadcast..."
> +      host1.broadcast (0, Packet ("SuperJoe"))
> diff -urdN enet-old/pyenet/setup.py enet/pyenet/setup.py
> --- enet-old/pyenet/setup.py	2003-10-30 07:55:32.000000000 -0800
> +++ enet/pyenet/setup.py	2003-11-01 04:32:25.000000000 -0800
> @@ -7,16 +7,24 @@
>  import sys, os, os.path
>  from distutils.core import setup, Extension
>  
> -source_dirs = ['..', '.']
> +source_dirs = ['..']
>  define_macros = [('HAS_GETHOSTBYNAME_R', None),
>                   ('HAS_GETHOSTBYADDR_R', None),
>                   ('HAS_POLL', None),
>                   ('HAS_FCNTL', None),
>                   ('HAS_MSGHDR_FLAGS', None) ]
>  
> -source_files = []
>  libraries = []
>  
> +# For enet.pyx
> +
> +os.system("pyrexc enet.pyx")
> +source_files = ['enet.c']
> +
> +# For pyenet
> +
> +#source_files = ['pyenet.c']
> +
>  # Build a list of all the source files
>  for dir in source_dirs:
>      for file in os.listdir(dir):
> @@ -32,7 +40,7 @@
>  setup(name="enet", version="0.1",
>        ext_modules=[Extension("enet", 
>                               source_files,
> -                             include_dirs=["../include"],
> +                             include_dirs=["../include/"],
>  			     define_macros=define_macros,
>  			     libraries=libraries,
>  			     library_dirs=[]
> diff -urdN enet-old/pyenet/test/Client.py enet/pyenet/test/Client.py
> --- enet-old/pyenet/test/Client.py	2003-05-22 15:17:24.000000000 -0700
> +++ enet/pyenet/test/Client.py	2003-11-01 03:18:17.000000000 -0800
> @@ -1,17 +1,19 @@
> -import enet
> -
> -host = enet.host(1, 28 * 1024, 9 * 1024)
> -peer = host.connect(('127.0.0.1', 5000), 2)
> -print '* CLIENT: Connected to localhost 5000:', peer
> -result, event = host.service(10000)
> -for i in range(10):
> -    if 0 < result:
> -        if enet.EVENT_RECEIVE == event.type:
> -            print '* CLIENT: Channel', event.channel, 'Received', event.data
> -        msg = 'ping' + str(i)
> -        print '* CLIENT: Sending', msg
> -        peer.send(0, msg, 0)
> -
> -host.flush()
> -peer.disconnect()
> -
> +import enet
> +
> +host = enet.Host (None, 28 * 1024, 9 * 1024)
> +peer = host.connect (enet.Address ('127.0.0.1', 5000), 2)
> +
> +print '* CLIENT: Connected to localhost 5000:', peer
> +
> +event = host.service (10000)
> +
> +for i in range (10) :
> +      if enet.EVENT_TYPE_RECEIVE == event.type :
> +          print '* CLIENT: Channel', event.channelID, 'Received', event.packet.data
> +
> +      msg = 'ping ' + str (i)
> +      print '* CLIENT: Sending', msg
> +      peer.send (0, enet.Packet (msg))
> +
> +host.flush ()
> +peer.disconnect ()
> diff -urdN enet-old/pyenet/test/Server.py enet/pyenet/test/Server.py
> --- enet-old/pyenet/test/Server.py	2003-05-22 15:17:24.000000000 -0700
> +++ enet/pyenet/test/Server.py	2003-11-01 03:19:47.000000000 -0800
> @@ -1,13 +1,11 @@
> -import enet
> -
> -host = enet.host(('127.0.0.1', 5000), 16, 56 * 1024, 14 * 1024)
> -print '* SERVER: Created and listening on port 5000:', host
> -while 1:
> -    result, event = host.service(60000)
> -    if 0 < result:
> -        if enet.EVENT_RECEIVE == event.type:
> -            print '* SERVER: Received Chan:', event.channel, 'Data:', event.data
> -    elif -1 == result:
> -        print '* SERVER: Problem servicing host'
> -        break
> -
> +import enet
> +
> +host = enet.Host(enet.Address ('127.0.0.1', 5000), 16, 56 * 1024, 14 * 1024)
> +
> +print '* SERVER: Created and listening on port 5000:', host
> +
> +while 1:
> +  event = host.service(60000)
> +
> +  if enet.EVENT_TYPE_RECEIVE == event.type:
> +    print '* SERVER: Received Chan:', event.channelID, 'Data:', event.packet.data




> _______________________________________________
> ENet-discuss mailing list
> ENet-discuss at cubik.org
> http://lists.cubik.org/mailman/listinfo/enet-discuss



More information about the ENet-discuss mailing list