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