Sockets con python

Xavier Barnada xbarnada en gmail.com
Mar Jun 2 19:10:17 CEST 2009


Hola, estoy modificando un codigo que he econtrado en internet que es un
bouncer/intermediario de IRC.El problema que tengo es que la segunda vez
que lo ejecuto queda la direcion ocupada y no se inicia a no ser que lo
haga con otro puerto o que espere un rato.Lo he ejecutado en modo debug
con Eric(uso Gnu/Linux) y sale que ejecuta los close.He programado cosas
con socket pero en c y supongo que no deberia ser muy distinto en python

El codigo es este:

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

# ////////////////////////////////////////////
# // pyTERRA v.1                            //
# // by KOMPASO :: kompaso en hotmail.com      //
# // marzo 2007                             //
# //                                        //
# // Descripcion: pyTERRA es un 'bouncer'   //
# // escrito en Python que recibe/envia     //
# // mensajes al/del chat de Terra          //
# //                                        //
# // Este script lo ha hecho uno que tiene  //
# // poca idea de programacion. Si consigues//
# // mejorarlo, por favor envia una copia   //
# // al correo electronico de arriba.       //
# ////////////////////////////////////////////

import socket
import select
import time

version = 'pyTERRA v.1'

#Definimos servidores y puertos: primero el de terra y despues el local
tserver = 'chfl.terra.es'
tport = 6969
bserver = '127.0.0.1'
bport = 6667   
bienvenida = 'Bienvenido a pyTERRA v.1\r\nConectando con Terra
ahora...\n\r\n\r\n\r'

#Creamos el socket de conexion a Terra
t = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
t.connect ( ( tserver, tport ) )

#Abrimos un puerto local para que haga de bouncer
b = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
b.bind ( ( bserver, bport ) )
b.listen ( 1 )

#Establecemos la conexion con terra segun el protocolo que exige
time.sleep ( 3 )
t.send ( '<raw>PASS null</raw>\r\n' )
time.sleep ( 2 )
t.send ( '<raw>NICK sid</raw>\r\n' )
time.sleep ( 2 )
t.send ( '<raw>USER A04 - - chatFlashXML</raw>\r\n' )


conex_activas = [ b , t ]
bouncer , info = b.accept()
print 'Conexion establecida con ' , info , '\r\n'
bouncer.send ( bienvenida )

def desconectar ( ) :
  # Cerramos las conexiones cuando se termina el bucle
  bouncer.close()
  t.close()
  b.close()
  
conex_activas.append ( bouncer )
tdata = ''
basura = ''
con=1;
#Bucle que escucha los sockets
while con==1:
  read , write , error = select.select( conex_activas , [] , [] , 1 )
  for x in read:
    if x == t: # ENTRA MENSAJE DE TERRA
      tdata = basura + x.recv ( 4096 )
      if not tdata: break # Sale del bucle si se rompe la conexion con
Terra
      #Respuesta PONG al PING de Terra para mantener viva la conexion
con Terra
      if tdata.find ( 'PING' ) != -1:
        print 'PING...',
        t.send ( '<raw>PONG ' + tdata.split( ) [ 1 ] + '</raw>\r\n' )
        print 'PONG'

      # Formatea el mensaje de XML de Terra:
      # Formato de Terra: <irc src="" a0="" ... aX="" cmd="" rest=""/>\r
\n\x00
      # Formato de IRC estandar: server_name nick_name command :message
      tdata = tdata.replace ( '"' , '' ) ; tdata = tdata.replace
( 'rest=' , ':' )
      tdata = tdata.replace ( ' />' , '' ) ; tdata = tdata.replace
( '<irc src=' , ':' )
      tdata = tdata.replace ( 'cmd=' , '' ) ; tdata = tdata.replace
( 'a0=' , '' )
      tdata = tdata.replace ( 'a1=' , '' ) ; tdata = tdata.replace
( 'a2=' , '' )
      tdata = tdata.replace ( 'a3=' , '' ) ; tdata = tdata.replace
( 'a4=' , '' )
      tdata = tdata.replace ( 'a5=' , '' ) ; tdata = tdata.replace
( 'a6=' , '' )
      tdata = tdata.replace ( 'a7=' , '' ) ; tdata = tdata.replace
( 'a8=' , '' )
      tdata = tdata.replace ( 'a9=' , '' ) ; tdata = tdata.replace
( 'a10=' , '' )
      tdata = tdata.replace ( 'a11=' , '' ) ; tdata = tdata.replace
( 'a12=' , '' )
      tdata = tdata.replace ( 'a13=' , '' ) ; tdata = tdata.replace
( 'a14=' , '' )
      tdata = tdata.replace ( 'a15=' , '' ) ; tdata = tdata.replace
( 'a16=' , '' )
      tdata = tdata.replace ( 'a17=' , '' ) ; tdata = tdata.replace
( 'a18=' , '' )

      # Divide el mensaje en lineas ( en Terra acaban en \r\n\x00 )
      tlines = tdata.split ( '\x00' )
      c = 1 ; basura = ''
      for tmsg in tlines :
        if tmsg != "":
          if c == len ( tlines ) : basura = tmsg
          else : bouncer.send( tmsg ) # Se envia la linea al cliente IRC
        print tmsg #imprime la linea lista para enviar de Terra para
debug
	c += 1
      tdata = ''

    if x == bouncer: # Entra mensaje del cliente
      bdata = bouncer.recv ( 4096 )
      print(bdata);
      if not bdata: break # Sale del bucle si se rompe la conexion con
el cliente IRC
      # Transformamos la codificacion UTF-8 de los clientes IRC a
iso-8859-1 que solo acepta Terra
      try:
        bdata = unicode ( bdata , 'utf-8' ).encode( 'iso-8859-1' )
      except:
        pass
      # Ignoramos la identificacion enviada por el cliente IRC porque
este bouncer ya la hace automaticamente
      if bdata.find( 'USER' ) != -1: bdata = 'IGNORANDO'
      if bdata.find( '/LIST' ) != -1: 
            print("\n>>Has fet list<<");
            t.send ( '<raw>' + bdata + '</raw>\r\n\x00' ) ;
            
      print "CLIENTE IRC --> " , bdata # imprime el mensaje del cliente
IRC para debug
      if bdata.find( 'QUIT' ) != -1: 

            print ("\nDesconectant");
            con=0;
      
      else:
        if (bdata != "IGNORANDO") : 
            t.send ( '<raw>' + bdata + '</raw>\r\n\x00' ) ;
desconectar ( )



------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes


Más información sobre la lista de distribución Python-es