Foros del Web » Programando para Internet » Python »

Chat sencillo TCP

Estas en el tema de Chat sencillo TCP en el foro de Python en Foros del Web. Bueno la cosa es que quiero crear un chat para ver como van los sockets y demás, la cosa es que si no escribo nada ...
  #1 (permalink)  
Antiguo 28/12/2013, 10:35
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Chat sencillo TCP

Bueno la cosa es que quiero crear un chat para ver como van los sockets y demás, la cosa es que si no escribo nada y lo envio se corta la comunicacion.Lo he intentado solucionar pero no he conseguido nada.
Aqui dejo los codigos:

CLIENTE
Código Python:
Ver original
  1. #!/usr/bin/env python
  2.  
  3. import socket
  4.  
  5. # creamos el socket
  6. clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  7. # ahora acemos que se conecte con el servidor
  8. clientsocket.connect(('localhost',8000))
  9.  
  10. # este bucle hace que mientras este conectado  haga lo que pone en el interior
  11. while 1:
  12.         data = raw_input('>') #funcion que hace que podamos escribir para mandarlo posteriormente
  13.         if data != " ":  # si no ai datos no lo envia
  14.             clientsocket.send(data)# enviamos los datos que hemos escrito
  15.         else:
  16.               print "No has escrito nada"
  17.         newdata = clientsocket.recv(1024) # recibimos los datos que envie el servidor
  18.         print 'servidor: %s' % newdata # y con esto lo escribimos en pantalla
  19. clientsocket.close() # cerramos el socket

SERVIDOR
Código Python:
Ver original
  1. #!/usr/bin/env python
  2.  
  3. import socket
  4.  
  5. # creamos el socket
  6. serversocket    =   socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  7. # usamos esta funcion para mantener en eschucha el puerto que queramos este caso 8000
  8. serversocket.bind(('localhost', 8000))
  9. # mantenemos en escucha el servidor
  10. serversocket.listen(1)
  11. # aceptamos la conexion
  12. clientsocket, clientaddress = serversocket.accept()
  13. print 'Conexion desde: ', clientaddress # escribimos la ip del cliente
  14. # mientras estamos conectados hace lo que este dentro del bucle
  15. while 1:
  16.         data = clientsocket.recv(1024) # recibimos datos del cliente
  17.         print 'cliente %s' % data # ponemos en pantalla lo que nos a dicho el cliente
  18.         newdata = raw_input('>') # escribimos lo que queramos enviar
  19.         if  newdata != " ":  # si no hay datos no lo enviamos
  20.           clientsocket.send(newdata) # enviamos lo que hemos escrito                
  21. clientsocket.close() # cerramos el socket
  #2 (permalink)  
Antiguo 28/12/2013, 21:16
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Chat sencillo TCP

Ok, no se cual sea el problema.

Pero si quieres hacer un chat de sockets robusto pero sencillo. Puedes usar select.

server.py
Código Python:
Ver original
  1. import select
  2. import socket
  3. import sys
  4. import Queue
  5.  
  6. # Create a TCP/IP socket
  7. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  8. server.setblocking(0)
  9.  
  10. # Bind the socket to the port
  11. server_address = ('localhost', 10000)
  12. print >>sys.stderr, 'starting up on %s port %s' % server_address
  13. server.bind(server_address)
  14.  
  15. # Listen for incoming connections
  16. server.listen(5)
  17.  
  18. # Sockets from which we expect to read
  19. inputs = [ server ]
  20.  
  21. # Sockets to which we expect to write
  22. outputs = [ ]
  23.  
  24. # Outgoing message queues (socket:Queue)
  25. message_queues = {}
  26.  
  27. while inputs:
  28.     # Wait for at least one of the sockets to be ready for processing
  29.     print >>sys.stderr, '\nwaiting for the next event'
  30.     readable, writable, exceptional = select.select(inputs, outputs, inputs)
  31.    
  32.     # Handle inputs
  33.     for s in readable:
  34.         if s is server:
  35.             # A "readable" server socket is ready to accept a connection
  36.             connection, client_address = s.accept()
  37.             print >>sys.stderr, 'new connection from', client_address
  38.             connection.setblocking(0)
  39.             inputs.append(connection)
  40.  
  41.             # Give the connection a queue for data we want to send
  42.             message_queues[connection] = Queue.Queue()
  43.         else:
  44.             data = s.recv(1024)
  45.             if data:
  46.                 # A readable client socket has data
  47.                 print >>sys.stderr, 'received "%s" from %s' % (data, s.getpeername())
  48.                 message_queues[s].put(data)
  49.                 # Add output channel for response
  50.                 if s not in outputs:
  51.                     outputs.append(s)
  52.             else:
  53.                 # Interpret empty result as closed connection
  54.                 print >>sys.stderr, 'closing', client_address, 'after reading no data'
  55.                 # Stop listening for input on the connection
  56.                 if s in outputs:
  57.                     outputs.remove(s)
  58.                 inputs.remove(s)
  59.                 s.close()
  60.  
  61.                 # Remove message queue
  62.                 del message_queues[s]
  63.     # Handle outputs
  64.     for s in writable:
  65.         try:
  66.             next_msg = message_queues[s].get_nowait()
  67.         except Queue.Empty:
  68.             # No messages waiting so stop checking for writability.
  69.             print >>sys.stderr, 'output queue for', s.getpeername(), 'is empty'
  70.             outputs.remove(s)
  71.         else:
  72.             print >>sys.stderr, 'sending "%s" to %s' % (next_msg, s.getpeername())
  73.             s.send(next_msg)
  74.     # Handle "exceptional conditions"
  75.     for s in exceptional:
  76.         print >>sys.stderr, 'handling exceptional condition for', s.getpeername()
  77.         # Stop listening for input on the connection
  78.         inputs.remove(s)
  79.         if s in outputs:
  80.             outputs.remove(s)
  81.         s.close()
  82.  
  83.         # Remove message queue
  84.         del message_queues[s]

client.py
Código Python:
Ver original
  1. import socket
  2. import sys
  3.  
  4. messages = [ 'This is the message. ',
  5.              'It will be sent ',
  6.              'in parts.',
  7.              ]
  8. server_address = ('localhost', 10000)
  9.  
  10. # Create a TCP/IP socket
  11. socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
  12.           socket.socket(socket.AF_INET, socket.SOCK_STREAM),
  13.           ]
  14.  
  15. # Connect the socket to the port where the server is listening
  16. print >>sys.stderr, 'connecting to %s port %s' % server_address
  17. for s in socks:
  18.     s.connect(server_address)
  19.  
  20. for message in messages:
  21.     # Send messages on both sockets
  22.     for s in socks:
  23.         print >>sys.stderr, '%s: sending "%s"' % (s.getsockname(), message)
  24.         s.send(message)
  25.  
  26.     # Read responses on both sockets
  27.     for s in socks:
  28.         data = s.recv(1024)
  29.         print >>sys.stderr, '%s: received "%s"' % (s.getsockname(), data)
  30.         if not data:
  31.             print >>sys.stderr, 'closing socket', s.getsockname()
  32.             s.close()

Supongo que puedes modificar esto para que funcione como un chat.
  #3 (permalink)  
Antiguo 29/12/2013, 09:59
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: Chat sencillo TCP

Muchas Gracias,enseguida me pongo a ello!
  #4 (permalink)  
Antiguo 29/12/2013, 10:53
 
Fecha de Ingreso: enero-2012
Ubicación: Buenos Aires
Mensajes: 745
Antigüedad: 12 años, 11 meses
Puntos: 35
Respuesta: Chat sencillo TCP

Probaste...

Código Python:
Ver original
  1. if not data:

En lugar de...

Código Python:
Ver original
  1. if data != " ":

Ya que no es lo mismo. En el primero verificas que la cadena está vacía, en el segundo verificas que la cadena no sea un espacio.

Espero que te sirva!
  #5 (permalink)  
Antiguo 30/12/2013, 13:52
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: Chat sencillo TCP

Cita:
Iniciado por carbon Ver Mensaje
Probaste...

Código Python:
Ver original
  1. if not data:

En lugar de...

Código Python:
Ver original
  1. if data != " ":

Ya que no es lo mismo. En el primero verificas que la cadena está vacía, en el segundo verificas que la cadena no sea un espacio.

Espero que te sirva!
Gracias me ha servido!No soluciona lo del que se desconecte pero has mejorado el codigo.
  #6 (permalink)  
Antiguo 30/12/2013, 20:16
 
Fecha de Ingreso: enero-2012
Ubicación: Buenos Aires
Mensajes: 745
Antigüedad: 12 años, 11 meses
Puntos: 35
Respuesta: Chat sencillo TCP

Bueno probé el código y el problema es que si el usuario no ingresa nada en el cliente, no vovlés a preguntar, entonces se queda esperando una respuesta a un mensaje que nunca fué enviado. Así que deberías reemplazar esto:
Código Python:
Ver original
  1. if data != " ":  # si no ai datos no lo envia
  2.     clientsocket.send(data)# enviamos los datos que hemos escrito
  3. else:
  4.       print "No has escrito nada"
Por esto:
Código Python:
Ver original
  1. if data:  # si no ai datos no lo envia
  2.     clientsocket.send(data)# enviamos los datos que hemos escrito
  3. else:
  4.     print "No has escrito nada, vuelve a intentarlo."
  5.     continue # Vuelve a comenzar el bucle

Por cierto tenes como medio una ensalada de espacios en el código, a veces haces indentaciones de 8 espacios y a veces de 2, selecciona un patrón y seguilo en todo el código, aunque lo más común es usar 4 espacios.

Espero que te sirva!

  #7 (permalink)  
Antiguo 31/12/2013, 07:15
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: Chat sencillo TCP

Muchas Gracias!Me ha servido de mucho!Una duda,se podria poner de alguna manera lo de recibir los datos
Cita:
newdata = clientsocket.recv(1024)
en segunda plano,no se si me explico.
Un saludo
  #8 (permalink)  
Antiguo 31/12/2013, 12:11
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Chat sencillo TCP

Puedes usar threads. O como recomendé select para envio y recepción de datos.

Pero como raw_input bloquea el programa puedes usar un thread para leer desde el teclado (raw_input) y otro para envio/recepcion de datos del socket e imprimir esos datos.
  #9 (permalink)  
Antiguo 01/01/2014, 08:41
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: Chat sencillo TCP

Gracias!Ahora me informo!
  #10 (permalink)  
Antiguo 05/01/2014, 14:11
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: Chat sencillo TCP

He empezado con los threads,(ya se que "thread" es basto y simple pero era mucho mas simple que threading).
El error que me arroja sera tonto pero mis conocimientos son muy limitados.Solo he modificado la parte del cliente y todavia no me he puesto con el "select".
Codigo:
Código Python:
Ver original
  1. #!/usr/bin/env python
  2. import thread
  3. import socket
  4.  
  5. # creamos el socket
  6. clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  7. # ahora acemos que se conecte con el servidor
  8. clientsocket.connect(('localhost',8000))
  9. def escribir_texto():
  10.          data = raw_input('>') #funcion que hace que podamos escribir para mandarlo posteriormente
  11. # este bucle hace que mientras este conectado  haga lo que pone en el interior
  12. while True:
  13.     thread.start_new_thread(escribir_texto, ())
  14.     if data:  # si no hay datos, no lo envia
  15.         clientsocket.send(data)# enviamos los datos que hemos escrito
  16.     else:
  17.         print "No has escrito nada, vuelve a intentarlo."
  18.         continue # Vuelve a comenzar el bucle
  19.     newdata = clientsocket.recv(1024) # recibimos los datos que envie el servidor
  20.     print 'servidor: %s' % newdata # y con esto lo escribimos en pantalla
  21. clientsocket.close() # cerramos el socket

Error:
Cita:
Traceback (most recent call last):
Un Saludo

Última edición por roberkas98; 05/01/2014 a las 14:35
  #11 (permalink)  
Antiguo 05/01/2014, 15:31
Avatar de Carlangueitor
Moderador ლ(ಠ益ಠლ)
 
Fecha de Ingreso: marzo-2008
Ubicación: México
Mensajes: 10.037
Antigüedad: 16 años, 9 meses
Puntos: 1329
Respuesta: Chat sencillo TCP

No estás mostrando el error. Pegalo completo.
__________________
Grupo Telegram Docker en Español
  #12 (permalink)  
Antiguo 05/01/2014, 17:03
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Chat sencillo TCP

Usando solo select y sockets.

Código Python:
Ver original
  1. import select
  2. import socket
  3. import sys
  4. import re
  5.  
  6.  
  7. CONNECTION_LIMIT = 10
  8. HOST, PORT = 'localhost', 8080
  9.  
  10. # Create a TCP/IP socket
  11. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  12. server.setblocking(0)
  13.  
  14. # Bind the socket to the port
  15. server_address = (HOST, PORT)
  16. print >>sys.stderr, 'starting up on %s port %s' % server_address
  17. server.bind(server_address)
  18.  
  19. # Listen for incoming connections
  20. server.listen(10)
  21.  
  22. # Sockets from which we expect to read
  23. inputs = [ server ]
  24.  
  25. # Sockets to which we expect to write
  26. outputs = [ ]
  27.  
  28. # User list
  29. users = {}
  30.  
  31. def broadcast(sockets, message):
  32.     for s in sockets:
  33.         s.send(message)
  34.  
  35. while True:
  36.     readable, writable, exceptional = select.select(inputs, outputs, inputs)
  37.    
  38.     # Handle inputs
  39.     for s in readable:
  40.         if s is server:
  41.             # A "readable" server socket is ready to accept a connection
  42.             connection, client_address = s.accept()
  43.             connection.setblocking(0)
  44.  
  45.             inputs.append(connection)
  46.             outputs.append(connection)
  47.  
  48.             users[connection] = "nameless"
  49.             username = users[connection]
  50.             broadcast(outputs, '%s has enter' % username)
  51.         else:
  52.             data = s.recv(1024)
  53.             if data:
  54.                 # A readable client socket has data
  55.                 data = data.strip()
  56.                 m = re.match(r'^/nick (\w+)$', data, re.I)
  57.                 if m:
  58.                     old_username = users[s]
  59.                     users[s] = m.group(1)
  60.                     data = '%s is now %s' % (old_username, users[s])
  61.                 else:
  62.                     data = "%s > %s" % (users[s], data)
  63.                 broadcast(outputs, data)
  64.             else:
  65.                 # Stop listening for input on the connection
  66.                 username = users[s]
  67.                 outputs.remove(s)
  68.                 inputs.remove(s)
  69.                 s.close()
  70.                 broadcast(outputs, '%s has left' % username)
  71.        
  72.  
  73.     # Handle "exceptional conditions"
  74.     for s in exceptional:
  75.         # Stop listening for input on the connection
  76.         inputs.remove(s)
  77.         outputs.remove(s)
  78.         s.close()

Código Python:
Ver original
  1. # client.py
  2. import socket
  3. import sys
  4. import select
  5. import Queue
  6.  
  7. HOST, PORT = 'localhost', 8080
  8. server_address = (HOST, PORT)
  9.  
  10. # Create a TCP/IP socket
  11. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  12.  
  13. # Connect the socket to the port where the server is listening
  14. print >>sys.stderr, 'connecting to %s port %s' % server_address
  15. sock.connect(server_address)
  16.  
  17.  
  18. inputs = [sys.stdin, sock]
  19. outputs = [sock]
  20. queue = Queue.Queue()
  21.  
  22. while True:
  23.     readable, writable, exceptional = select.select(inputs, outputs, inputs)
  24.  
  25.     for r in readable:
  26.         if r is sys.stdin:
  27.             message = sys.stdin.readline()
  28.             queue.put(message)
  29.         elif r is sock:
  30.             data = sock.recv(1024)
  31.             if not data:
  32.                 sock.close()
  33.                 print "Connection closed"
  34.                 sys.exit(0)
  35.             else:
  36.                 print data
  37.            
  38.     for w in writable:
  39.         if w is sock:
  40.             try:
  41.                 next_msg = queue.get_nowait()
  42.                 sock.send(next_msg)
  43.             except Queue.Empty:
  44.                 pass
  45.  
  46.     for ex in exceptional:
  47.         if ex is sock:
  48.             sock.close()

PD: Esto no funcionara en windows. El servidor si, pero el cliente no.
  #13 (permalink)  
Antiguo 06/01/2014, 07:15
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: Chat sencillo TCP

Cita:
Iniciado por Carlangueitor Ver Mensaje
No estás mostrando el error. Pegalo completo.

Es eso lo que me arroja por pantalla.Yo tan solo lo he pegado.

Un saludo
  #14 (permalink)  
Antiguo 06/01/2014, 07:17
 
Fecha de Ingreso: noviembre-2013
Mensajes: 61
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: Chat sencillo TCP

Cita:
Iniciado por razpeitia Ver Mensaje
Usando solo select y sockets.

Código Python:
Ver original
  1. import select
  2. import socket
  3. import sys
  4. import re
  5.  
  6.  
  7. CONNECTION_LIMIT = 10
  8. HOST, PORT = 'localhost', 8080
  9.  
  10. # Create a TCP/IP socket
  11. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  12. server.setblocking(0)
  13.  
  14. # Bind the socket to the port
  15. server_address = (HOST, PORT)
  16. print >>sys.stderr, 'starting up on %s port %s' % server_address
  17. server.bind(server_address)
  18.  
  19. # Listen for incoming connections
  20. server.listen(10)
  21.  
  22. # Sockets from which we expect to read
  23. inputs = [ server ]
  24.  
  25. # Sockets to which we expect to write
  26. outputs = [ ]
  27.  
  28. # User list
  29. users = {}
  30.  
  31. def broadcast(sockets, message):
  32.     for s in sockets:
  33.         s.send(message)
  34.  
  35. while True:
  36.     readable, writable, exceptional = select.select(inputs, outputs, inputs)
  37.    
  38.     # Handle inputs
  39.     for s in readable:
  40.         if s is server:
  41.             # A "readable" server socket is ready to accept a connection
  42.             connection, client_address = s.accept()
  43.             connection.setblocking(0)
  44.  
  45.             inputs.append(connection)
  46.             outputs.append(connection)
  47.  
  48.             users[connection] = "nameless"
  49.             username = users[connection]
  50.             broadcast(outputs, '%s has enter' % username)
  51.         else:
  52.             data = s.recv(1024)
  53.             if data:
  54.                 # A readable client socket has data
  55.                 data = data.strip()
  56.                 m = re.match(r'^/nick (\w+)$', data, re.I)
  57.                 if m:
  58.                     old_username = users[s]
  59.                     users[s] = m.group(1)
  60.                     data = '%s is now %s' % (old_username, users[s])
  61.                 else:
  62.                     data = "%s > %s" % (users[s], data)
  63.                 broadcast(outputs, data)
  64.             else:
  65.                 # Stop listening for input on the connection
  66.                 username = users[s]
  67.                 outputs.remove(s)
  68.                 inputs.remove(s)
  69.                 s.close()
  70.                 broadcast(outputs, '%s has left' % username)
  71.        
  72.  
  73.     # Handle "exceptional conditions"
  74.     for s in exceptional:
  75.         # Stop listening for input on the connection
  76.         inputs.remove(s)
  77.         outputs.remove(s)
  78.         s.close()

Código Python:
Ver original
  1. # client.py
  2. import socket
  3. import sys
  4. import select
  5. import Queue
  6.  
  7. HOST, PORT = 'localhost', 8080
  8. server_address = (HOST, PORT)
  9.  
  10. # Create a TCP/IP socket
  11. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  12.  
  13. # Connect the socket to the port where the server is listening
  14. print >>sys.stderr, 'connecting to %s port %s' % server_address
  15. sock.connect(server_address)
  16.  
  17.  
  18. inputs = [sys.stdin, sock]
  19. outputs = [sock]
  20. queue = Queue.Queue()
  21.  
  22. while True:
  23.     readable, writable, exceptional = select.select(inputs, outputs, inputs)
  24.  
  25.     for r in readable:
  26.         if r is sys.stdin:
  27.             message = sys.stdin.readline()
  28.             queue.put(message)
  29.         elif r is sock:
  30.             data = sock.recv(1024)
  31.             if not data:
  32.                 sock.close()
  33.                 print "Connection closed"
  34.                 sys.exit(0)
  35.             else:
  36.                 print data
  37.            
  38.     for w in writable:
  39.         if w is sock:
  40.             try:
  41.                 next_msg = queue.get_nowait()
  42.                 sock.send(next_msg)
  43.             except Queue.Empty:
  44.                 pass
  45.  
  46.     for ex in exceptional:
  47.         if ex is sock:
  48.             sock.close()

PD: Esto no funcionara en windows. El servidor si, pero el cliente no.


Por que no funcionaria el cliente?

Un saludo

Etiquetas: chat, tcp
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:13.