Dec 15, 2013 08:21 PM
(This post was last modified: Aug 8, 2015 08:59 AM by King of Hearts.)
Hey,
Today I'll be showing you how to make a chat server and client in python. But before I do, I'd like to thank ๖ۣۜ1x1x1x1 for his tutorial on networking in python which caught my eye and showed me how awesome python really is. This is my first program in python, so feel free to leave constructive feedback. Note: Even though this was my first program in python, it is by no means my first program. I'm going to assume, you have at least some knowledge of programming.
You can view the full source code here
Now on with the tutorial. We will first be writing the server.
First we will import three things. Go ahead and
Next we will make the socket. The socket is the connection handler. It receives the data the client will send us. The socket is going to be of type TCP (Google this if you need to). We will then bind it to localhost and any random port (should be above 1050). Next we will specify how many clients at most to handle simultaneously.
And then some print statements and initializing a dictionary to store connected clients.
After this, I made two functions. The first is called acceptNewConnections and as the name suggests it accepts new connections. I've added comments to show you what the code is doing.
The second function I made was the listen function. This one also has comments to help you out:
Lastly, I started the acceptConnections Thread and set a while loop to keep the main thread running as well:
Now the Client:
Again start with the imports:
Now here I defined the two main functions first. The first function is the send function which listens for user input and sends it to the client.
The next function is the listen function. This method listens for the data from the server and prints it.
Above, I defined the functions. However, I haven't called them or done anything else with the program yet. Now I'll make a socket and try to connect to the server:
Now that I'm connected, I have to set my name and make sure it's available:
Now that we are connected all we have to do is start the listen and send threads:
Feel free to pm me for help or post here. As a challenge, you should try to add private messaging.
It only takes 2 seconds to say thanks.
Today I'll be showing you how to make a chat server and client in python. But before I do, I'd like to thank ๖ۣۜ1x1x1x1 for his tutorial on networking in python which caught my eye and showed me how awesome python really is. This is my first program in python, so feel free to leave constructive feedback. Note: Even though this was my first program in python, it is by no means my first program. I'm going to assume, you have at least some knowledge of programming.
You can view the full source code here
Now on with the tutorial. We will first be writing the server.
First we will import three things. Go ahead and
PHP Code
<?php
import socket
import sys
import thread
PHP Code
<?php
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "localhost"
port = 9992
numberOfClients = 50
mysocket.bind((host, port))
mysocket.listen(numberOfClients)
PHP Code
<?php
print '--'
print 'Listening at ' + host + ':' + str(port)
print '--'
connected = {}
PHP Code
<?php
def acceptNewConnections():
while 1:#always listen for new connections
try:
conn, addr = mysocket.accept()#accept a new connection
name = conn.recv(1024)#the first connection will always be the name (done client sided)
if name:#checks to make sure the client did send something
if name in connected:#check if name is taken by someone already
conn.send('SERVER:NAME CHOSEN')#If it is taken tell that to the client
conn.close()#close the connection
else:#if name isn't taken
print name + ' Connected'
connected[name] = (conn, addr)#add the connection to the dictionary with key being name
print str(len(connected)) + " Users connected"
thread.start_new_thread(listen, (connected[name][0], connected[name][1], name))#starts the thread which will listen to connections from that socket.
#if you don't know what threads are, they allow for your program to do more than 1 thing at once.
connectedNames = ''
for nameF,connF in connected.iteritems():#loop through the connected clients to tell new user joined
if not nameF is name:#make sure the new user isn't being told he joined
connF[0].send(name + " Joined the chat")
connectedNames += nameF + ', '# add the name of connected user to connectednames string
conn.send('SERVER:There are currently ' + str(len(connected)) + ' connected users: ' + connectedNames + name + '\nType ::help for help')
#send new user welcome message
except Exception, e:
print 'Erroraa ' + str(e)
pass
The second function I made was the listen function. This one also has comments to help you out:
PHP Code
<?php
def listen(conn,addr,name):#takes in the connection, the ip adress of connection and name as parameters
while 1:#always listens to specified client
try:
data = conn.recv(1024)#receives data with 1024 buffersize (if you don't know what it is leave it as is)
print str(data)
for nameF,connF in connected.iteritems():#loop through connected clients
if not nameF is name:#make sure the client isn't the same one who send the data
connF[0].send(data)#send the data to the other user
except Exception, e:
if '10054' in str(e):#this error means the connection is closed
print name + ' Left'
del connected[name]#delete the connection from the connected dictionary
for nameF,connF in connected.iteritems():#loop through connected clients
connF[0].send(name + " Left")#tell them that the user left
#notice there is no if here because I've already deleted the current connection from the connected dictionary
thread.exit()#stop the thread
else:
print str(e)
break
PHP Code
<?php
try:
thread.start_new_thread(acceptNewConnections, ())
except Exception, e:
print str(e)
print "Error: unable to start thread"
while 1:
pass
Now the Client:
Again start with the imports:
PHP Code
<?php
import socket
import thread
import sys
PHP Code
<?php
def send():
while 1:#always listen for input
str = raw_input("")#gets input from user
try:
if str == '::exit':#checks if str is a command to exit
mysocket.close()#if it is it's going to close the socket
sys.exit(0)#and exit the program
elif str == '::help':#else if the str is another command for help
print '\nHelp: \n\tTo exit tpe ::exit'#print help (you can add more stuff/commands if you'd like)
else:
mysocket.send(name + ": " + str)#send the server the name of the client + message
except Exception, e:
if '10054' in e:#means the server went offline
raw_input('Server disconnected. Press enter to exit')
sys.exit(0)
PHP Code
<?php
def listen():
while 1:#always listen
try:
data = mysocket.recv(1024)#get the data
print ">>" + data#print it with >> to show it's from the server/another user
except Exception, e:
if '10054' in str(e):#if server went offline:
raw_input('Server disconnected. Press enter to exit')
sys.exit(0)
PHP Code
<?php
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#make a new TCP socket in the IPv4 protocol
mysocket.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 30000, 30000))#make it so that it doesn't die out anytime soon.
#TCP sockets close after a certain amount of connections, here I set the amount to be 30000
host = "localhost"#server to connect to
port = 9992#port
try:
mysocket.connect((host, port))#try to connect to the server
except Exception, e:
print 'something\'s wrong. Exception type is %s' % (`e`)
raw_input('Can\'t connect. Press enter to close')#can't connect so close
sys.exit(0)
PHP Code
<?php
name = raw_input('Please enter your name: ')#ask user for the name
mysocket.send(name)#send it to the server
data = mysocket.recv(1024)#receive the response
while 1:
if 'NAME CHOSEN' in data:#see if response tells us if the name is chosen
mysocket.close();#if it is first close the current socket
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#remake the socket
mysocket.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 30000, 30000))#reset the minimum connection value
try:
mysocket.connect((host, port))#connect to the server again
except Exception, e:
print 'something\'s wrong. Exception type is %s' % (`e`)
raw_input('Can\'t connect. Press enter to close')
sys.exit(0)
name = raw_input('That name is chosen. Enter a different name ');#ask for the name again
mysocket.send(name);#send the name again
data = mysocket.recv(1024)#reset data to equal the response and go back to the top of the loop
else:#if name is available
print data#print the welcome message
break#get out the infinite loop because the name is available and we are connected
PHP Code
<?php
try:
thread.start_new_thread(send, ())#start the send thread
thread.start_new_thread(listen, ())#start the listening thread
except:
print "Error: unable to start thread"
while 1:#keep main thread running
pass
Feel free to pm me for help or post here. As a challenge, you should try to add private messaging.
It only takes 2 seconds to say thanks.



