Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python socket communication for client-server interaction #130

Merged
merged 2 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Welcome to PythonProjects, a repository filled with exciting and educational Pyt
- [Mastermind Game](#mastemind-game)
- [Sudoku](#sudoku)
- [Space Invaders](#space-invaders)
- [Socket Communication](#socket-communication)

## Beginner Level Projects

Expand Down Expand Up @@ -140,6 +141,8 @@ Embark yourself in a Sudoku quest. Perfect for learning object-oriented programm
### Space Invaders
A fun game of spaceships and spacewars!! Eliminate the enemies or you die ;) This is a perfect project for learning pygame module and game logic.

### Socket Communication
A project that showcases a basic Python socket communication setup for client-server interaction. The primary objective is to facilitate communication between a server and client nodes.

## Stats

Expand Down
45 changes: 45 additions & 0 deletions Socket Communication/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Python Socket Communication Setup

## Overview

This project showcases a basic Python socket communication setup for client-server interaction. The primary objective is to facilitate communication between a server and client nodes.

## Server Side

1. Create a server socket.
2. Bind it to a specified IP and port.
3. Listen and accept incoming client connections.
4. Handle communication with connected clients.
5. Close the server socket when done.

## Client Side

1. Create a client socket.
2. Connect to the server using the server's IP and port.
3. Send requests or data to the server.
4. Close the client socket when communication is complete.

## Execution

1. Ensure you have Python installed. This project is compatible with Python 3.6 and above.
2. Set up a Python virtual environment: `python -m venv myenv`.
3. Activate the virtual environment:
- On Windows: `myenv\Scripts\activate`.
- On macOS and Linux: `source myenv/bin/activate`.
4. Install the required Python version mentioned in [requirements.md](requirements.md).
5. Run the server script: `python server.py`.
6. Run the client script: `python client.py`.

## Results

The server and client scripts should run without any errors. The server script should display the following output:

Server and client connection established.
![Server and Client](assets/client_server_connection.png)

Multiple clients can connect to the server at the same time.
![Multiple Clients and Server](assets/multipleclient_server_connection.png)

## Conclusion

This project provides a straightforward example of setting up a Python socket communication system. You can adapt and modify the scripts to suit your specific requirements.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 63 additions & 0 deletions Socket Communication/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Required imports
import socket
import time

# Constants
PORT = 5050
HEADER = 60
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "Disconnected !!!"

# Get the local machine's IP address as the server address
SERVER = socket.gethostbyname(socket.gethostname())
Address = (SERVER, PORT)

# Creating a socket instance
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to the server
client.connect(Address)


# Function to send messages
def send(msg):
"""
Sends a message to the server.

Parameters:
- msg (str): The message to be sent.

Returns:
None
"""
# Encoding the message
message = msg.encode(FORMAT)
msg_length = len(message)

# Ensure the header is always HEADER bytes by padding with spaces if needed
send_length = str(msg_length).encode(FORMAT)
send_length += b" " * (HEADER - len(send_length))

# Sending the message
client.send(send_length)
client.send(message)

# Receive and print acknowledgment from the server
print(client.recv(2048).decode(FORMAT))


# Sending messages
send("Hello server socket. Client socket here.")
time.sleep(1) # Introducing a delay using time.sleep() instead of input()

send("Let's make a connection by applying the fundamentals of networking and socket.")
time.sleep(1)

send("Bye!!!")
time.sleep(1)

# Disconnecting from the server
send(DISCONNECT_MESSAGE)

# Close the socket connection
client.close()
3 changes: 3 additions & 0 deletions Socket Communication/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Requirements

This project is compatible with Python 3.6 and above. While it has been tested with Python 3.12.0, it is likely to work with other versions within the Python 3 series. Compatibility with very early releases of Python 3 is not guaranteed.
96 changes: 96 additions & 0 deletions Socket Communication/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Required imports
import socket
import threading

# Constants
HEADER = 60
FORMAT = "utf-8"

# Port for the socket to listen on
PORT = 5050

DISCONNECT_MESSAGE = "Disconnected !!!"

# Get the local machine's IP address as the server address
SERVER = socket.gethostbyname(socket.gethostname())
Address = (SERVER, PORT)

# Create a socket instance
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the specified address and port
server.bind(Address)


def handle_client(conn, addr):
"""
Handles a client connection.

Parameters:
- conn (socket): The client connection socket.
- addr (tuple): The address of the client (IP, port).

Returns:
None
"""
print(f"[NEW CONNECTION] {addr} is connected.")
connected = True

while connected:
# Receive the message length
msg_length = conn.recv(HEADER).decode(FORMAT)

if msg_length:
msg_length = int(msg_length)
# Receive the actual message
msg = conn.recv(msg_length).decode(FORMAT)

if msg == DISCONNECT_MESSAGE:
connected = False

print(f"[{addr}] {msg}")

# Send a received message acknowledgment to the client
conn.send("[MESSAGE] is received".encode(FORMAT))

conn.close() # Close the connection with the client


def start():
"""
Starts the server and handles incoming connections.

Parameters:
None

Returns:
None
"""
server.listen()
print(f"[SERVER] Server is listening on {SERVER}")

# A forever loop until interrupted or an error occurs
while True:
try:
(conn, addr) = server.accept()

# Start a new thread for each client
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()

# Print the number of active connections
print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 1}")

except KeyboardInterrupt:
print("\n[SERVER] Server shutting down...")
break

except Exception as e:
print(f"[ERROR] An error occurred: {e}")

server.close() # Close the server socket


if __name__ == "__main__":
print("[SERVER] Server is starting !!!")
start()