""" BobClient.py --- Simple Chat Client that runs the Bob Protocol. Bob stands for ... Um.... Nevermind. BobClient is threaded to allow one thread to wait on user input, while another thread processes the network connection. BobClient's goal is to send an arbitrarily long message to the server and recieve that message back. In fact, messages sent by other clients to the Server will also get echoed back onto All BobClients. This is how we create our little chat program. """ import thread, time, sys from socket import socket, AF_INET, SOCK_STREAM # Bob Protocol import Protocol # We need to pickle these messages for transmission import pickle # Build a Client Object: class Client: def __init__(self, HOSTNAME, username): self.HOSTNAME = HOSTNAME self.PORTS = [7777,7778] self.username = username self.DONE = 0 #------------ Threaded Stuff ----------------# # I'm using PORTS 7777 and 7778 def Chat(self): # Start two threads, one reading, one writing thread.start_new(self.ChatRead, (self.PORTS[0],self.username,)) thread.start_new(self.ChatWrite, (self.PORTS[1],self.username,)) # We need a loop here, if this # function exists it kills the # threads. while not self.DONE: time.sleep(0.1) return def ChatRead(self, PORT,username): print "Client Initializing READS" # Initialize Network Connection readsock = socket(AF_INET, SOCK_STREAM) readsock.connect((self.HOSTNAME, PORT)) self.Read(PORT, username, readsock) while not self.DONE: data = readsock.recv(1024) if not data: continue data = pickle.loads(data) print data readsock.close() return def Read(self, PORT, username, readsock): # Create Connect _READ_ Message connect = Protocol.ConnectRead(username) # PIckle and send the connect message as a string readsock.send(pickle.dumps(connect)) return def Write(self, PORT, username, writesock): # Create Connect _WRITE_ Message connect = Protocol.ConnectWrite(username) # Generate a join message to make sure # "< username joined the chat >" get's printed ASAP join = Protocol.Message(username, "\\join") join.isCommand() print join.str() writesock.send(pickle.dumps(connect)) writesock.send(pickle.dumps(join)) return def ChatWrite(self, PORT, username): print "Client Initializing WRITES" # Initialize Network Connection writesock = socket(AF_INET, SOCK_STREAM) writesock.connect((self.HOSTNAME, PORT)) self.Write( PORT, username, writesock) while not self.DONE: data = raw_input(">") if data == "": continue else: # Actual Message or Command Data message = Protocol.Message(username,data) # Turn plain message into command if necessary message.isCommand() writesock.send(pickle.dumps(message)) time.sleep(0.2) writesock.close() return if __name__=="__main__": if len(sys.argv) == 2: Bob = Client("",sys.argv[1]) Bob.Chat() else: name = raw_input("Please enter a name to chat:") host = raw_input("Connect to(Enter for Default):") Bob = Client(host,name) Bob.Chat() #------------ Testing Functions --------------# # These may be useful if you rewrite them # to use the new message objects. ## message = ["Ping!"] ## def pingBob(): ## sockobj = socket(AF_INET, SOCK_STREAM) ## sockobj.connect((HOSTNAME, PORT)) ## for line in message: ## sockobj.send(line) ## data = sockobj.recv(1024) ## print 'Client received:', `data` ## sockobj.close() ## return ## def autoBob(message): ## sockobj = socket(AF_INET, SOCK_STREAM) ## sockobj.connect((HOSTNAME, PORT)) ## done = 0 ## for i in range(6): ## time.sleep(1) ## sockobj.send(message) ## data = sockobj.recv(1024) ## print 'Client received:', `data` ## sockobj.close() ## return # I'm not going to bother implementing these until # They are supported on the server # and the Client is Object Oriented. ## if data.find("")>0 and data.find("")>0: ## cmd = Protocol.splitCommand(data) ## password = cmd[1].split(":")[1] ## message = Protocol.Message(username, ## "Server Is Exiting!", data, password) ## elif data == "": ## message = Protocol.Message(username,"left the building.","") ## print "Client Exiting..." ## time.sleep(1.0) ## break ## # Not sure how to implement Nick at the moment ## # Let's not worry about it for now. ## ## elif data.find("")>0 and data.find("")>0: ## ## cmd = Protocol.splitCommand(data) ## ## newname = cmd[1] ## ## message = Protocol.Message(newname, " <=> "+username, data) ## elif data.find("")>0 and data.find("")>0: ## cmd = Protocol.splitCommand(data) ## password = cmd[1].split(":")[1] ## message = Protocol.Message(username, data, data, password) ## elif data.find("")>0: ## cmd = Protocol.splitCommand(data) ## emotion = cmd[1] ## message = Protocol.Message(username, emotion, data)