[Tutor] Learning Python with a Simple IM
Jorge Louis De Castro
jorge at bcs.org.uk
Sun Jul 10 14:01:03 CEST 2005
Hello,
I am a Java Developer that wants to learn Python by doing. I am loving this initial vibe I'm getting out of Python. However, because I feel programmers of a certain languages bring with them certain vices when moving to other languages, I'd like to have feedback from seasoned Python programmers regarding my code.
Using some socket examples I've googled here and there I wrote the very simple Instant-Messaging-wannabe program below. I was advised to post the code here and get feedback from this community.
In my next iteration with this code I'll be changing the client to include a server thread listening instead of polling the server.
Regards
jorge
THE SIMPLE IM CLIENT
import socket, threading, time, msvcrt
print "Please enter the following information"
_url = raw_input("URL: ")
_port = raw_input("Port: ")
print "Starting IIM client on port: " + _port
socketOut = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socketOut.connect((_url, int(_port)))
# clear screen here
print "Enter your user details"
_from = raw_input("User id: ")
_to = raw_input("Buddy id: ")
print '\n'
print "Connecting to server..."
print '\n'
# send user details and receive response
socketOut.sendall('@@@'+_from+'##'+_to)
response = socketOut.recv(8192)
def listener():
while 1:
time.sleep(5)
socketOut.sendall('$$$'+_from)
response = socketOut.recv(8192)
if response != " ":
print "\n" + response
if response == 'AUTH_OK':
data = ""
th = threading.Thread(target=listener)
th.setDaemon(1)
th.start()
print "Background polling thread started"
while 1:
if msvcrt.kbhit():
ch = msvcrt.getche()
else:
ch = None
if ch:
if ch != '\r':
data += ch
else:
print '\n'
socketOut.sendall('###'+_from+'##'+data)
response = socketOut.recv(8192)
if response != " ":
print response
data = ""
else:
print "Auhentication failed!"
socketOut.close()
THE SIMPLE IM SERVER
import SocketServer
_port = 8881
_clients = {}
# a connected client
class Client:
# queue of messages sent to this client
queue = []
def __init__(self, _sock, _src, _dest):
print "Creating IM client"
self.socket = _sock
print "Incoming socket: %s" % self.socket
self.user = _src
print "Username: " + self.user
# buddies should be a list
self.buddy = _dest
print "Buddy: " + self.buddy
print "Created IM client"
# the server handling requests
class Broker(SocketServer.BaseRequestHandler):
def handle(self):
print "Connected from", self.client_address
while True:
receivedData = self.request.recv(8192)
if not receivedData:
break
# if handshake packet, extract client details
if receivedData.startswith('@@@',0,3):
print "Received handshake packet"
# strip handshake code
receivedData = receivedData.replace('@@@', '', 1).lstrip()
l = receivedData.split('##',1)
socket = self.request
src = l[0]
dest = l[1]
c = Client(socket, src, dest)
# use username as key on hashmap
_clients[src] = c
# send success message
socket.sendall('AUTH_OK')
print "Client " + src + " authenticated"
# if polling packet, extract sender details and send messages
if receivedData.startswith('$$$',0,3):
# strip polling message
print "Received polling packet"
src = receivedData.replace('$$$', '', 1).lstrip()
# only poll if more than 1 user
if len(_clients) > 1:
# use username as key on hashmap
_clients[src] = c
if len(c.queue) < 1:
c.socket.sendall(" ")
else:
msgs = ""
for q in c.queue:
msgs += q + '\n'
# send queued messages
c.socket.sendall(msgs)
c.queue = []
print "Sent all pending messages for " + c.user
else:
socket.sendall(" ")
# if message packet, extract data and append to target queue
if receivedData.startswith('###',0,3):
print "Received message packet"
receivedData = receivedData.replace('###', '', 1).lstrip()
l = receivedData.split('##',1)
src = l[0]
text = l[1]
if text.strip != "":
print "Message not empty"
# extract client
clientSrc = _clients[src]
# ...and its buddy
clientDest = _clients[clientSrc.buddy]
msg = src+": "+text
print "Appended message to queue of " + clientSrc.buddy
clientDest.queue.append(msg)
print "Queue of: " + clientDest.user + " = %s" % clientDest.queue
clientDest.socket.sendall(" ")
else:
if len(_clients) < 2:
self.request.sendall(receivedData)
for c in _clients.values():
if self.request == c.socket:
c.socket.close()
# remove from hashmap
del _clients[c.user]
print "Removed " + c.user + " from hashmap"
print "Disconnected from", self.client_address
srv = SocketServer.ThreadingTCPServer(('',_port),Broker)
print "Started IIM server on port %d" % _port
srv.serve_forever()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20050710/27bd37a2/attachment.htm
More information about the Tutor
mailing list