GUIChatApplicationInPythonTkinter-CopyAssignment 1724530793371
GUIChatApplicationInPythonTkinter-CopyAssignment 1724530793371
SEARCH….
SITEMAP
Introduction
Python
Abstract This is a GUI-based chat application using which up to 5 clients can join
Online C++ Editor
and talk in real time. This project uses Tkinter, socket, and threading
library.
Online C Editor
Language/s Used: Python
Socket: A socket looks and behaves much like a low-level file descriptor. In Unix,
every I/O action is done by writing or reading a file descriptor. A file descriptor is just
an integer associated with an open file and it can be a network connection, a text file,
a terminal, or something else. A socket is bound to a port number so that the TCP
layer can identify the application that the data is destined to be sent. On the client
side, the client knows the hostname of the machine on which the server is running
and the port number to which the server is listening.
To make a connection request. If everything goes well, the server accepts the
connection. Upon acceptance, the server gets a new socket bound to the same local
port and also has its remote and endpoint set to the address and port of the client.
Threading: Message threads are a running commentary of all the messages sent in
your chat app. They appear within a group, private message, or channel. Threads
appear in chat rooms, emails, and even the comment section of blogs. Learning how
to master the art of threaded conversations will improve your teamwork.
Coding server.py
When a new client connects, we add it to our collection of client sockets while
listening for forthcoming client connections. For each client that is connected, start
a new thread that continuously monitors the client for any incoming messages and
broadcasts them to all other clients. The code below establishes a TCP socket, binds
it to the server IP, and then waits for incoming connections:
#imports
import socket
import threading
class ChatServer:
clients_list = []
last_received_message = ""
def __init__(self):
self.server_socket = None
self.create_listening_server()
#listen for incoming connection
def create_listening_server(self):
I’ve specified “127.0.0.1” as the server IP address. This includes all IPv4 addresses
on the computer. You might be wondering why we don’t just use localhost or
“0.0.0.0” instead. So, if the server has two IP addresses, say “192.168.1.2” on one
network and “10.0.0.1” on another, it will listen on both.
1 #imports
2 import socket
3 import threading
4
5
6 class ChatServer:
7
8 clients_list = []
9
10 last_received_message = ""
11
12 def __init__(self):
13 self.server_socket = None
14 self.create_listening_server()
15 #listen for incoming connection
16 def create_listening_server(self):
17
18 self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #create a socket us
19 local_ip = '127.0.0.1'
20 local_port = 10319
21 # this will allow you to immediately restart a TCP server
22 self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
23 # this makes the server listen to requests coming from other computers on the network
24 self.server_socket.bind((local_ip, local_port))
25 print("Listening for incoming messages..")
26 self.server_socket.listen(5) #listen for incomming connections / max 5 clients
27 self.receive_messages_in_a_new_thread()
28 #fun to receive new msgs
29 def receive_messages(self, so):
30 while True:
31 incoming_buffer = so.recv(256) #initialize the buffer
32 if not incoming_buffer:
33 break
34 self.last_received_message = incoming_buffer.decode('utf-8')
35 self.broadcast_to_all_clients(so) # send to all clients
36 so.close()
37 #broadcast the message to all clients
38 def broadcast_to_all_clients(self, senders_socket):
39 for client in self.clients_list:
40 socket, (ip, port) = client
41 if socket is not senders_socket:
42 socket.sendall(self.last_received_message.encode('utf-8'))
43
44 def receive_messages_in_a_new_thread(self):
45 while True:
46 client = so, (ip, port) = self.server_socket.accept()
47 self.add_to_clients_list(client)
48 print('Connected to ', ip, ':', str(port))
49 t = threading.Thread(target=self.receive_messages, args=(so,))
50 t.start()
51 #add a new client
52 def add_to_clients_list(self, client):
53 if client not in self.clients_list:
54 self.clients_list.append(client)
55
56
57 if __name__ == "__main__":
58 ChatServer()
When recv() is called, it will wait for data to arrive. If no data is available, recv() will
not return (it ‘blocks’) and the program pauses until data arrives. Calls like accept()
and recv() that make the program wait until some new data has arrived, allowing it to
return, are called blocking calls. Data is sent and received over the network as
bytestrings, and hence need to be encoded and decoded using encode() and
decode() respectively.
recv() takes in one argument, bufsize, which specifies the maximum amount of data
to be received at once.
send(), on the other hand, sends data from the socket to its connected peer.
One problem with both send() and recv() is that there is a slight possibility that only
part of the data is sent or received because the outgoing or incoming buffers are
almost full, so it queues whatever data it could while leaving the rest of the data
unprocessed. This becomes problematic when send() returns, but in fact, some of
the data is still left unsent. We could put send() in a loop, or we could use sendall()
as a simple way to say “I want to send all of the data”.
I hope I was able to explain much of the theory to you when developing the server
script. The same criteria apply here, except that we have a Send thread that is always
waiting for command-line user input. We will add a graphical user interface later, but
it will follow much of the same philosophy. Any data received will be displayed on the
client interface, and any data sent will be processed by the server to be broadcast to
other connected clients.
Again, we make use of multithreading. This time, it is to let the sending and receiving
operations run alongside each other. This way, our chatroom is real-time (instead of
alternating between send() and recv() calls).
We’re not quite finished yet, but how about creating a graphical user interface?
Tkinter, which is included in the Python standard library, will be used.
We only need to make a few changes to client.py and add some extra code to
construct the GUI. Reading the documentation for Tkinter will teach you more about
it, but it is outside the scope of this lesson.
1 from tkinter import Tk, Frame, Scrollbar, Label, END, Entry, Text, VERTICAL, Button, messagebox #T
2 import socket #Sockets for network connection
3 import threading # for multiple proccess
4
5
6
7 class GUI:
8 client_socket = None
9 last_received_message = None
10
11 def __init__(self, master):
12 self.root = master
13 self.chat_transcript_area = None
14 self.name_widget = None
15 self.enter_text_widget = None
16 self.join_button = None
17 self.initialize_socket()
18 self.initialize_gui()
19 self.listen_for_incoming_messages_in_a_thread()
20
21 def initialize_socket(self):
22 self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # initialazing sock
23 remote_ip = '127.0.0.1' # IP address
24 remote_port = 10319 #TCP port
25 self.client_socket.connect((remote_ip, remote_port)) #connect to the remote server
26
27 def initialize_gui(self): # GUI initializer
28 self.root.title("Socket Chat")
29 self.root.resizable(0, 0)
30 self.display_name_section()
31 self.display_chat_entry_box()
32 self.display_chat_box()
33
34
35
36 def listen_for_incoming_messages_in_a_thread(self):
37 thread = threading.Thread(target=self.receive_message_from_server, args=(self.client_socket,
38 thread.start()
39 #function to recieve msg
40 def receive_message_from_server(self, so):
41 while True:
42 buffer = so.recv(256)
43 if not buffer:
44 break
45 message = buffer.decode('utf-8')
46
47 if "joined" in message:
48 user = message.split(":")[1]
49 message = user + " has joined"
50 self.chat_transcript_area.insert('end', message + '\n')
51 self.chat_transcript_area.yview(END)
52 else:
53 self.chat_transcript_area.insert('end', message + '\n')
54 self.chat_transcript_area.yview(END)
55
56 so.close()
57
58 def display_name_section(self):
59 frame = Frame()
60 Label(frame, text='Enter Your Name Here! ', font=("arial", 13,"bold")).pack(side='left', pady=20)
61 self.name_widget = Entry(frame, width=60,font=("arial", 13))
62 self.name_widget.pack(side='left', anchor='e', pady=15)
63 self.join_button = Button(frame, text="Join", width=10, command=self.on_join).pack(side='righ
64 frame.pack(side='top', anchor='nw')
65
66 def display_chat_box(self):
67 frame = Frame()
68 Label(frame, text='Chat Box', font=("arial", 12,"bold")).pack(side='top', padx=270)
69 self.chat_transcript_area = Text(frame, width=60, height=10, font=("arial", 12))
70 scrollbar = Scrollbar(frame, command=self.chat_transcript_area.yview, orient=VERTICAL)
71 self.chat_transcript_area.config(yscrollcommand=scrollbar.set)
72 self.chat_transcript_area.bind('<KeyPress>', lambda e: 'break')
73 self.chat_transcript_area.pack(side='left', padx=15, pady=10)
74 scrollbar.pack(side='right', fill='y',padx=1)
75 frame.pack(side='left')
76
77 def display_chat_entry_box(self):
78 frame = Frame()
79 Label(frame, text='Enter Your Message Here!', font=("arial", 12,"bold")).pack(side='top', anchor=
80 self.enter_text_widget = Text(frame, width=50, height=10, font=("arial", 12))
81 self.enter_text_widget.pack(side='left', pady=10, padx=10)
82 self.enter_text_widget.bind('<Return>', self.on_enter_key_pressed)
83 frame.pack(side='left')
84
85 def on_join(self):
86 if len(self.name_widget.get()) == 0:
87 messagebox.showerror(
88 "Enter your name", "Enter your name to send a message")
89 return
90 self.name_widget.config(state='disabled')
91 self.client_socket.send(("joined:" + self.name_widget.get()).encode('utf-8'))
92
93 def on_enter_key_pressed(self, event):
94 if len(self.name_widget.get()) == 0:
95 messagebox.showerror("Enter your name", "Enter your name to send a message")
96 return
97 self.send_chat()
98 self.clear_text()
99
100 def clear_text(self):
101 self.enter_text_widget.delete(1.0, 'end')
102
103 def send_chat(self):
104 senders_name = self.name_widget.get().strip() + ": "
105 data = self.enter_text_widget.get(1.0, 'end').strip()
106 message = (senders_name + data).encode('utf-8')
107 self.chat_transcript_area.insert('end', message.decode('utf-8') + '\n')
108 self.chat_transcript_area.yview(END)
109 self.client_socket.send(message)
110 self.enter_text_widget.delete(1.0, 'end')
111 return 'break'
112
113 def on_close_window(self):
114 if messagebox.askokcancel("Quit", "Do you want to quit?"):
115 self.root.destroy()
116 self.client_socket.close()
117 exit(0)
118
119 #the mail function
120 if __name__ == '__main__':
121 root = Tk()
122 gui = GUI(root)
123 root.protocol("WM_DELETE_WINDOW", gui.on_close_window)
124 root.mainloop()
125
Debug the server.py file first, then execute client.py. The GUI will appear after
executing client.py! You can have up to 5 clients.
I developed this so that you can interact with the program through the GUI, making it
easy to debug and observe what is going on behind the scenes.
Conclusion
We have created GUI Chat Application in Python Tkinter from scratch. We created
two important Python files client.py and server.py. Client file has been created for
the chat interface and the server file will handle the backend. That’s it. I sincerely
hope you liked reading it as much as I did writing it. This was only the tip of the
iceberg in the fascinating field of computer networking.
Also Read:
Create your own ChatGPT Bakery Management SQLite | CRUD Operations
with Python System in Python | Class 12 in Python
Project
Sales Management System Bank Management System Python Download File from
Project in Python Project in C++ URL | 4 Methods
GUI Piano in Python Ludo Game in Python Rock Paper Scissors Game
in Python
Snake and Ladder Game in Puzzle Game in Python Medical Store Management
Python System Project in Python
Creating Dino Game in Tic Tac Toe Game in Test Typing Speed using
Python Python Python App
Share: