程序代写代做代考 python Lab title – Chat room

Lab title – Chat room

Learning outcomes – Using Python socket programming to implement a chat room application

In this practical session, we are going to implement a chat room application using Python socket

programming. Unlike peer to peer chat, a chat room means multiple users can connect to a chat

server and send their messages. Every message is broadcasted to every connected chat user. We

need to implement both the chat server and the chat client – the user.

1. Chat server

The chat server should be able to:

 Accept connections from multiple clients

 Read the messages from each client and broadcast them to all connected clients.

To handle multiple clients, we use the select function from the select module to monitor all sockets.

read_sockets,write_sockets,error_sockets = select.select(rlist,wlist,xlist[,timeout])

The inputs are lists of sockets that we expect to read from (rlist), we expect to write to (wlist), and

can possibly go wrong (xlist). The outputs are subsets of the corresponding lists of sockets that are

ready to read from, ready to write to, and have exceptional conditions. The select function waits

until at least one of the sockets to be ready for processing, or time out.

Use the select function in the chat server:

If any of the client sockets is readable, the server reads the message from that socket and sends the
message to all other client sockets. The broadcast is implemented using the following function:

The following is the full implementation of the chat server. In the code, the server use port 5000 to
listen to for incoming connections. The clients must connect to the same port. You can change the
port number if you want.

# Get the list sockets which are ready to be read through select
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])

# Function to broadcast chat messages to all connected clients
def broadcast_data (sock, message):

#Do not send the message to server socket and the client who has sent us the message
for socket in CONNECTION_LIST:

if socket != server_socket and socket != sock :

socket.send(message.encode())

# ChatServer.py
import socket

import select

#Function to broadcast chat messages to all connected clients
def broadcast_data (sock, message):

#Do not send the message to server socket and the client who has sent us the message
for socket in CONNECTION_LIST:

if socket != server_socket and socket != sock :

socket.send(message.encode())

if __name__ == “__main__”:

# List to keep track of socket descriptors
CONNECTION_LIST = []

RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2
HOST = ”

PORT = 5000

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

server_socket.bind((HOST, PORT))

server_socket.listen(10)

# Add server socket to the list of readable connections
CONNECTION_LIST.append(server_socket)

print (“Chat server started on port ” + str(PORT))

while 1:

# Get the list sockets which are ready to be read through select
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])

for sock in read_sockets:

#New connection
if sock == server_socket:

# Handle the case in which there is a new connection received
sockconn, addr = server_socket.accept()

CONNECTION_LIST.append(sockconn)

print (“Client (%s, %s) connected” % addr)

broadcast_data(sockconn, “[%s:%s] entered room\n” % addr)

#Some incoming message from a client
else:

# Handle data recieved from client
data = sock.recv(RECV_BUFFER).decode()

if data:

broadcast_data(sock,”\r”+’<'+str(sock.getpeername())+'> ‘+data)

else:

# broken socket connection, chat client pressed ctrl+c for example
CONNECTION_LIST.remove(sock)

broadcast_data(sock, “\n Client %s is offline\n” %str(sock.getpeername()))

print (“Client %s is offline” %str(sock.getpeername()))

sock.close()

server_socket.close()

2. Chat Client

The chat client should:

1. Listen to messages from the server.

2. Check the user input. If the user types in a message, send it to the server.

The client has to listen to both the server socket s and the user input – stdin. Again, we use the select

function to monitor the two possible input streams.

Note: The above is not going to work on windows. It uses the select function to read data from both
the socket and the input stream. This works on Linux because Linux treats sockets and file
descriptors in the same manner, therefore the select function is able to read from stdin. On windows
the select function will not read anything except sockets created by the winsock socket functions.

Then the client will do relevant processing depends on which socket is readable. If the server socket

is readable, the client will read the message and print it. If the stdin socket is readable, it means the

user has typed a message to be sent. The client will read the message and send it to the server.

The following is the full implementation of the chat client. Again port 5000 is used in the code.

See next page for the code.

3. Run the chat room on your own computer

Open a console on your computer and run the chat server:

python ChatServer.py

Open multiple consoles on your computer and run the chat client in each console:

python ChatClient.py localhost 5000

You can use 127.0.0.1 instead of localhost.

Now type messages + Enter key from any client console. You are chatting now.

4. Chat with your friends

Group with your neighbours, and nominate one to run the chat server on his/her computer.

Find out the IP address of the server using ~$ifconfig

Everyone in the group run a chat client:

python ChatClient.py ipaddr 5000

where ipaddr is the IP address of the server that you just found.

If the server is running on your computer, then open a new console and run the chat client:

python ChatClient.py localhost 5000

Now start chatting.

socket_list = [sys.stdin, s]

# Get the list sockets which are readable
read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])

# ChatClient.py
import socket

import select

import string

import sys

def prompt() :

sys.stdout.write(‘ ‘)

sys.stdout.flush()

#main function
if __name__ == “__main__”:

if (len(sys.argv) < 3) : print ('Usage : python ChatClient.py hostname port') sys.exit() host = sys.argv[1] port = int(sys.argv[2]) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(2) # connect to remote host try : s.connect((host, port)) except : print ('Unable to connect') sys.exit() print ('Connected to remote host. Start sending messages') prompt() try: while 1: socket_list = [sys.stdin, s] # Get the list sockets which are readable read_sockets, write_sockets, error_sockets = select.select(socket_list , [], []) for sock in read_sockets: #incoming message from remote server if sock == s: data = sock.recv(4096).decode() if not data : print ('\nDisconnected from chat server') sys.exit() else : #print data sys.stdout.write(data) prompt() #user entered a message else : msg = sys.stdin.readline() s.send(msg.encode()) prompt() except KeyboardInterrupt: #If user Ctrl+C close the socket politely s.close() print ("Socket to server closed")