Change language

Simple chat using Python

| |

This article demonstrates — How to set up a simple chat server and allow multiple clients to connect to it using client script. The code uses the concept of sockets and streams.

Socket programming

Sockets can be thought of as endpoints in a communication channel that is bi-directional and establishes communication between the server and one or more clients. Here, we set up a socket on each end and let the client communicate with other clients through the server. The server side socket is associated with some server side hardware port. Any client that has a socket associated with the same port can communicate with the server socket.

Multithreading

Stream — it is a subprocess that runs a set of commands separately from any other thread. Thus, each time a user connects to the server, a separate thread is created for him, and communication between the server and the client occurs on separate threads based on the socket objects created to identify each client.
We will need two scripts to create this chat room. One to maintain service and the other — to start each client to connect to the server.

Server side script

The server side script will try to establish a socket and bind it to an IP address and the port specified by the user (Windows users may have to make an exception for the specified port number in their firewall settings, or it may use a port that is already open). The script will then remain open and receive connection requests and add the appropriate socket objects to the list to track active connections. Each time a user connects,
a separate thread will be created for that user. In each thread, the server waits for a message and sends this message to other users who are currently in the chat. If the server encounters an error while trying to receive a message from a specific stream, it will exit that stream.

use

This server can be configured on the local network by selecting any of the computers as the server host and using that computer’s private IP address as the server’s IP address.
For example, if a local network is assigned a set of private IP addresses in the range from 192.168.1.2 to 192.168.1.100, then any computer of these 99 nodes can act as a server, and the rest of the nodes can connect to the server node using the private IP address of the server. Care must be taken to select a port that is not currently being used. For example, port 22 is the default for ssh, and port 80 — default for HTTP protocols. Thus, these two ports should preferably not be used or reconfigured to make them free to use.
However, if the server is supposed to be accessible outside the local network, a public IP address is required to use it. This will require port forwarding in cases where a host on the LAN (a host other than a router) wishes to host a server. In this case, we would require that any requests coming to public IP addresses be redirected to our private IP address on our local network and therefore require port forwarding.
For more information on port forwarding: link

To run the script, simply download it from the GitHub link at the bottom of the post and save it somewhere convenient on your computer.

 / * Both the server and client script can then be run from the Command prompt (in Windows) or from bash Terminal (Linux users) by simply typing "python chat_server.py" or "python client.py". For example, * / python chat_server.py 192.168.55.13 8081 python client.py 192.168.55.13 8081 

Below is a server-side script that must run constantly for chat to work.

# Python program for implementing the chat server side.

import socket

import select

import sys

from thread import *

  
& quot; & quot; & quot; The first AF_INET argument is the address area
connector. This is used when we have an Internet domain with
any two hosts The second argument is the socket type.
SOCK_STREAM means data or characters are read into
continuous stream.

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

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

 
# checks if sufficient arguments were provided

if len (sys.argv)! = 3 :

  pri nt "Correct usage: script, IP address, port number"

exit ()

 
# takes the first argument from the command line as an IP address

IP_address = str (sys.argv [ 1 ])

 
# takes the second argument from the command line as a port number

Port = int (sys.argv [ 2 ])

 
"" "
attached directs the server to the entered IP address and
the specified port number.
The client should be aware of these parameters
"" "
server.bind ((IP_address, Port))

 
"" "
listens for 100 active connections. This number can be
increased for convenience.
"" "

server.listen ( 100 )

 

list_of_clients = []

 

def clientthread (conn, addr):

 

# sends a message to the client whose custom object is conn

conn.send ( "Welcome to this chatroom!" )

 

while True :

try :

  message = conn.recv ( 2048 )

  if message:

 

  " "" prints message and address

user who just sent a message to the server

Terminal & quot; & quot; & quot;

print "& lt;" + addr [ 0 ] + "& gt; " + message

  

# Calls the broadcast function to send a message to everyone

message_to_send = "& lt;" + addr [ 0 ] + "" " + message

  broadcast (message_to_send, conn)

 

else :

  & quot; & quot; & quot; message may have no content if connection

  is broken, in this case we are removing the connection & quot; & quot; & quot;

remove (conn)

 

except :

continue

 
& quot; & quot; & quot; Using the function below, we broadcast the message to all
clients whose object does not match the submitting
message & quot; & quot; & quot;

def broadcast (message, connection):

for clients in list_of_clients:

if clients! = connection:

try :

clients.send (message)

except :

clients.close ()

 

# if the link doesn’t work, we remove the client

remove (clients)

  
& quot; & quot; & quot; The following function simply removes the object
from the list that was created at the beginning
program & quot; & quot ; & quot;

def remove (connection):

if connection in list_of_clients:

list_of_clients.remove (connection )

 

while True :

  

& quot; & quot; & quot; Accepts the connection request and stores two parameters,

conn, which is the socket object for this user, and addr

which contains the IP address of the client, which is simply

associated & quot; & quot; & quot;

  conn, addr = server.accept ()

 

& quot; & quot; & quot; Maintain a list of clients for broadcast convenience

message to all available people in the chat & quot; & quot; & quot;

list_of_clients.append (conn)

 

# prints the address of the newly connected user

print addr [ 0 ] + "connected"

 

# creates a separate thread for each user

  # what connects

start_new_thread (clientthread, (conn, addr)) 

 
conn.close ( )
server.close ()

Client side script

Client side script will simply try to access the server socket created with the specified IP address and port. Once it connects, it will continually check to see if the input is coming from the server or from the client and redirects the output accordingly. If the input is from the server, it displays a message on the terminal. If the input is from the user, it sends a message that users enter into the server to pass it on to other users.

This is the client-side script that each user should use to connect to server.

# Python program to implement the chat client.

import socket

import select

import sys

 

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

if len (sys.argv)! = 3 :

  print "Correct usage: script, IP address, port number"

exit ()

IP_address = str (sys.argv [ 1 ])

Port = int (sys.argv [ 2 ])

server.connect ((IP_address, Port))

  

while True :

 

  # maintains a list of possible input streams

  sockets_list = [sys.stdin, server]

 

& quot; & quot; & quot; There are two possible input situations.

user wants to enter manually to send to other people,

or the server sends a print message to

screen. Select returns from sockets_list, a stream that

the reader to enter. So, for example, if the server wants

to send a message, then the if condition will be met

below. If the user wants to send a message, the rest

status will be true & quot; & quot; & quot;

read_sockets, write_socket, error_socket = select.select (sockets_list, [], [])

 

for socks in read_sockets:

if socks = = server:

  message = socks.recv ( 2048 )

print message

else :

message = sys.stdin. readline ()

server.send (message)

sys.stdout.write ( ""You"" )

sys.stdout.write (message)

sys.stdout.flush ()

server.close ()

Output: In the figure below, the server was initialized from the left side of the terminal, and the client script & # 8212 ; on the right side of the terminal. (Terminal sharing is done with tmux, & # 39; sudo apt-get install tmux & # 39;). For initialization purposes, you can see that whenever a user submits a message, it is displayed along with the IP address on the server side.

The picture below is a basic conversation between two people on one server. Multiple clients can connect to the server the same way!

Link to download the script: link

This article is provided by Deepak Srivatsav . If you are as Python.Engineering and would like to contribute, you can also write an article using contribute.python.engineering or by posting an article contribute @ python.engineering. See my article appearing on the Python.Engineering homepage and help other geeks.

Please post comments if you find anything wrong or if you would like to share more information on the topic discussed above.

Shop

Learn programming in R: courses

$

Best Python online courses for 2022

$

Best laptop for Fortnite

$

Best laptop for Excel

$

Best laptop for Solidworks

$

Best laptop for Roblox

$

Best computer for crypto mining

$

Best laptop for Sims 4

$

Latest questions

NUMPYNUMPY

Common xlabel/ylabel for matplotlib subplots

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

12 answers

NUMPYNUMPY

Flake8: Ignore specific warning for entire file

12 answers

NUMPYNUMPY

glob exclude pattern

12 answers

NUMPYNUMPY

How to avoid HTTP error 429 (Too Many Requests) python

12 answers

NUMPYNUMPY

Python CSV error: line contains NULL byte

12 answers

NUMPYNUMPY

csv.Error: iterator should return strings, not bytes

12 answers

News


Wiki

Python | How to copy data from one Excel sheet to another

Common xlabel/ylabel for matplotlib subplots

Check if one list is a subset of another in Python

sin

How to specify multiple return types using type-hints

exp

Printing words vertically in Python

exp

Python Extract words from a given string

Cyclic redundancy check in Python

Finding mean, median, mode in Python without libraries

cos

Python add suffix / add prefix to strings in a list

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

Python - Move item to the end of the list

Python - Print list vertically