Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a simple command-line chat in Python?

Tags:

python

I study network programming and would like to write a simple command-line chat in Python.

I'm wondering how make receving constant along with inputing available for sending at any time.

As you see, this client can do only one job at a time:

from socket import *

HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

while 1:
    data = raw_input('> ')
    if not data: break
    tcpCliSock.send(data)
    data = tcpCliSock.recv(BUFSIZE)
    if not data: break
    print data

tcpCliSock.close()

So if another client sends a message, this client will only receive it after sending a message too. I bet you understand me. I have googled for the matter and found out many interesting things such as asynchronous I/O, threading, non-blocking synchronization, concurrent programming and so on. I have also installed the twisted package. In brief, I've been learning all these things but yet haven't found what I was looking for. (Of course, I will keep trying and trying until I get to the point.)

So, my question is how make that? =)

like image 401
user122922 Avatar asked Jun 20 '09 03:06

user122922


2 Answers

Your question was not very coherent. However, your program does not need to be asynchronous at all to attain what you are asking for.

This is a working chat script you originally wanted with minimal changes. It uses 1 thread for receiving and 1 for sending, both using blocking sockets. It is far simpler than using asynchronous methods.

from socket import *
from threading import Thread
import sys

HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

def recv():
    while True:
        data = tcpCliSock.recv(BUFSIZE)
        if not data: sys.exit(0)
        print data

Thread(target=recv).start()
while True:
    data = raw_input('> ')
    if not data: break
    tcpCliSock.send(data)

tcpCliSock.close()
like image 113
Unknown Avatar answered Sep 25 '22 18:09

Unknown


If you want to code it from scratch select is the way to go (and you can read on Google Book Search most of the chapter of Python in a Nutshell that covers such matters); if you want to leverage more abstraction, asyncore is usable, but Twisted is much richer and more powerful.

like image 45
Alex Martelli Avatar answered Sep 21 '22 18:09

Alex Martelli