TCP is used here because it ensures a reliable connection between the client (bank user) and the server (banking system). The connection is established, maintained, and closed properly, ensuring that all commands (like checking balance, depositing, or withdrawing) are processed sequentially without missing data.
import socket
# Create a TCP/IP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 65432))
server_socket.listen(1)
print("Banking server running...")
connection, client_address = server_socket.accept()
with connection:
print("Client connected:", client_address)
balance = 1000 # Initial balance
while True:
data = connection.recv(1024) # Receive data from the client
if not data:
break
message = data.decode()
if message == "check_balance":
response = f"Your balance is: ${balance}"
elif message.startswith("deposit"):
try:
amount = int(message.split()[1])
balance += amount
response = f"Deposited ${amount}. New balance: ${balance}"
except ValueError:
response = "Invalid deposit amount."
elif message.startswith("withdraw"):
try:
amount = int(message.split()[1])
if amount <= balance:
balance -= amount
response = f"Withdrew ${amount}. New balance: ${balance}"
else:
response = "Insufficient funds."
except ValueError:
response = "Invalid withdrawal amount."
else:
response = "Invalid command."
connection.sendall(response.encode()) # Send the response back to the client
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 65432))
while True:
message = input("Enter command (check_balance, deposit <amount>, withdraw <amount>): ")
client_socket.sendall(message.encode()) # Send the command to the server
data = client_socket.recv(1024) # Receive the server's response
print("Server:", data.decode())
client_socket.close()
Connection-Oriented: In this scenario, a client and server establish a connection before exchanging data. The communication follows a sequence, and the connection must be maintained until the interaction is complete. This is typically done using TCP sockets.
Connectionless: In contrast, connectionless communication doesn't require an established connection. Data is sent as discrete packets with no guarantee of delivery or order. This is typically done using UDP sockets.
import socket
# Create a TCP/IP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 65432))
server_socket.listen(1)
print("Waiting for a connection...")
connection, client_address = server_socket.accept()
with connection:
print("Connection established with", client_address)
while True:
data = connection.recv(1024)
if not data:
break
print("Received:", data.decode())
connection.sendall(data) # Echo back the received data
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 65432))
message = "Hello, Server!"
client_socket.sendall(message.encode())
data = client_socket.recv(1024)
print("Received:", data.decode())
client_socket.close()
Connectionless socket programming is used for a simple calculator where the client sends individual operations (addition, subtraction, etc.) to the server, and the server responds without maintaining an ongoing connection. Each operation is sent as a separate packet over UDP.
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('localhost', 65432))
print("Calculator server running...")
while True:
data, address = server_socket.recvfrom(1024)
operation = data.decode()
print(f"Received operation: {operation} from {address}")
# Simple calculator logic
try:
result = eval(operation) # Don't use eval in production for security
response = f"Result: {result}"
except Exception as e:
response = f"Error: {str(e)}"
server_socket.sendto(response.encode(), address)
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('localhost', 65432)
while True:
operation = input("Enter operation (e.g., '2 + 2', '10 * 5'): ")
client_socket.sendto(operation.encode(), server_address)
data, server = client_socket.recvfrom(1024)
print("Server:", data.decode())
client_socket.close()
In this practice session, we learned about the key differences between connection-oriented (TCP) and connectionless (UDP) communication protocols. TCP, being reliable and ensuring ordered data delivery, is ideal for applications like banking or message boards where data integrity is crucial. On the other hand, UDP, being faster but less reliable, is suitable for tasks like a simple calculator where speed outweighs the need for guaranteed delivery. We implemented TCP socket programming to establish a connection between the client and server, processing requests such as checking balance or depositing money, while UDP socket programming enabled faster, independent message exchanges without maintaining a continuous connection. The session also highlighted the importance of choosing the right protocol for specific applications, considering factors like data reliability and speed. Lastly, we touched on security aspects, noting that in real-world applications, securing connections and validating input would be essential to prevent vulnerabilities like code injection. This session deepened our understanding of socket programming and its real-world applications, enhancing our practical skills in network communication.