o891 0 Newbie Poster

Hi guys,

I am trying to create a python chat server. So far, it has been going well but a problem has come up with threading.

The threading for incoming connections works fine (in the listen_and_accept function). Since I would like to be able to type in commands in the server terminal window, I though I would start two threads, one calling the command_line function and one to call the listen_and_accept funtion (which in turn would create threads for the incoming connections).

For some reason this. doesn't work. Could it be the indented threading? (Output from running the server (not much) is below). All the rest works fine so far...

Edit: Output is below. I know the code must look pretty stupid to you, but I am just getting started (a few days), any of-topic tips would also be greatly appreciated!

Thanks!

Code:

#!/usr/bin/env python

#########################################################
# Chat (client or server)
#########################################################
#
#	Author: Oliver Stollmann
#	Date: 17.11.09
#

import thread, sys, time
import socket as s

print "---------------------------------------------------"

# Check for valid call
if sys.argv.__len__() == 3:
	type = 'SERVER'
elif sys.argv.__len__() == 4:
	type = 'CLIENT'
else:
	sys.exit("Error! Usage: %s server:[name port], client:[nick_name host port]" % sys.argv[0])

class chat_server:
	
	def __init__(self, server_name, server_port, socket=None):
		'''Constructor'''
		# Chat server name
		self._SERVER_NAME = server_name
		# Chat server port
		self._SERVER_PORT = int(server_port)
		# Chat server IP
		self._SERVER_IP = s.gethostbyname(s.gethostname())
		
		# Socket: new/existing?
		if socket is None:
			self.socket = s.socket(s.AF_INET, s.SOCK_STREAM)
		else:
			self.socket = socket
		
		# clients[[socket, ip, id, name]]
		self.clients = []
		
		# Bind to socket
		self.bind(self._SERVER_IP, self._SERVER_PORT)
		# Server commands thread
		thread.start_new_thread(self.command_line, ('a','b')) # <---------- THIS ISNT THE PROBLEM (I think)
		# Listen thread
		thread.start_new_thread(self.listen_and_accept,('a', 'b')) # <---------- THIS IS THE PROBLEM (I think)
	
	def command_line(a,b,c):
		input = raw_input('> ')
		print input
	
	def bind(self, host, port):
		'''Socket bind'''
		try:
			self.socket.bind((host, port))
		except s.error:
			sys.exit("Error! Could not bind.")
	
	def listen_and_accept(self, a):
		self.socket.listen(5)
		'''listen for accept() requests'''
		print "Listening (" + str(self._SERVER_IP) + ":" + str(self._SERVER_PORT) + ")..."
		while True:
			c_socket, c_address = self.socket.accept()
			c_ip = c_address[0]
			c_id = c_address[1]
			c_name = c_socket.recv(1024)
			self.add_client(c_socket, c_ip, c_id, c_name)
			print 'New user: ' + str(c_name) + '@' + str(c_ip)
			thread.start_new_thread(self.handle, (c_socket, c_ip, c_id, c_name))
	
	def handle(self, c_socket, c_ip, c_id, c_name):
		'''handle client'''
		print 'New thread for user: ' + str(c_name) + '@' + str(c_ip)
#		time.sleep(2)
#		thread.exit()
#		print 'Thread closed!'
		while True:
			data = c_socket.recv(1024)
			if data == 'quit()':
				c_socket.send('GoodBye!')
				print 'User', str(c_ip), 'hast left the chat!'
				thread.exit()
				
			else:
				self.send(c_ip, c_id, c_name, data)
	
	def add_client(self, c_socket, c_ip, c_id, c_name):
		'''add client'''
		new_client = [c_socket, c_ip, c_id, c_name]
		self.clients.append(new_client)
	
	def remove_client(self, c_ip, c_id, c_name):
		'''remove client'''
		t = False
		for i in range(self.clients.__len__()):
			if self.clients[i][1] == c_ip and self.clients[i][2] == c_id and self.clients[i][3] == c_name:
				self.clients.remove(self.clients[i])
				t = True
		return t
	
	def check_client(self, c_ip, c_id, c_name):
		'''check client'''
		for i in range(self.clients.__len__()):
			if self.clients[i][1] == c_ip and self.clients[i][2] == c_id and self.clients[i][3] == c_name:
				c = client[i]
		return c
	
	def send(self, c_ip, c_id, c_name, data):
		'''Send message'''
		for client in self.clients:
			if client[1] != c_ip or client[2] != c_id or client[3] != c_name:
				# message body
				client[0].send(data)
		print 'Message from', str(c_ip), 'sent:', str(data)
	
	def details(self):
		'''Server details'''	
		print "Chat Server details:"
		print "  name:", self._SERVER_NAME
		print "  IP:", self._SERVER_IP
		print "  port", self._SERVER_PORT
	
	def quit(self):
			self.socket.close()
		
	
server1 = chat_server(sys.argv[1], sys.argv[2])

################
#	output:
#
#	mbp1:final mbp1$ python chat_server.py test 2408
#	---------------------------------------------------
#	mbp1:final mbp1$
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.