1
Current Location:
>
Network Programming
The Mysteries of Python Socket Programming: Building Network Applications from Scratch
Release time:2024-11-14 01:06:01 Number of reads 5
Copyright Statement: This article is an original work of the website and follows the CC 4.0 BY-SA copyright agreement. Please include the original source link and this statement when reprinting.

Article link: https://baogewang.com/en/content/aid/1864?s=en%2Fcontent%2Faid%2F1864

Opening Words

Have you ever wondered what happens behind the scenes when you open a webpage or use instant messaging software? Today, I'm going to talk to you about the most fundamental and important concept in Python network programming—socket programming. Through this article, we will unveil the mysteries of network communication.

Basic Concepts

Before we start coding, we need to understand a few key concepts. Imagine a socket as a telephone line between two programs, while an IP address and port number are like phone numbers. When you want to call someone, you need to know their number; similarly, for programs to communicate, they need to know each other's IP address and port number.

Let's first look at the two basic communication methods: TCP and UDP. TCP is like making a phone call; you need to connect first before talking, and it ensures the information is accurately transmitted. UDP is like sending a text message; once it's sent, you don't care if it's received or not.

Practical Tutorial

Now let's get hands-on. First, we'll write a simple chat program. This program includes both a server and client part. I often use this example to teach beginners because it's both intuitive and practical.

Server-side code:

import socket
import threading

def handle_client(client_socket, addr):
    """Function to handle client connections"""
    print(f"New connection from: {addr}")
    while True:
        try:
            # Receive client message
            msg = client_socket.recv(1024).decode('utf-8')
            if not msg:
                break
            print(f"Message from {addr}: {msg}")

            # Send reply
            response = f"Server has received your message: {msg}"
            client_socket.send(response.encode('utf-8'))
        except:
            break

    client_socket.close()

def start_server():
    """Start the server"""
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('0.0.0.0', 9999))
    server.listen(5)
    print("Server started, waiting for connections...")

    while True:
        client_socket, addr = server.accept()
        client_thread = threading.Thread(
            target=handle_client,
            args=(client_socket, addr)
        )
        client_thread.start()

if __name__ == '__main__':
    start_server()

You might ask how I wrote this code? Let me tell you my thought process: First, we need to create a socket, then bind it to a specified port, and then start listening for connection requests. When a new connection comes in, we create a new thread to handle it, allowing us to serve multiple clients simultaneously.

Client-side code:

import socket
import threading

def receive_messages(sock):
    """Function to receive server messages"""
    while True:
        try:
            msg = sock.recv(1024).decode('utf-8')
            print(f"
Received message: {msg}")
        except:
            break

def start_client():
    """Start the client"""
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(('localhost', 9999))

    # Create a thread to receive messages
    receive_thread = threading.Thread(target=receive_messages, args=(client,))
    receive_thread.start()

    try:
        while True:
            message = input("Enter message: ")
            if message.lower() == 'quit':
                break
            client.send(message.encode('utf-8'))
    finally:
        client.close()

if __name__ == '__main__':
    start_client()

Practical Tips

In actual development, I found a few tips particularly useful:

  1. Always remember to set a timeout to avoid indefinite blocking:
socket.settimeout(60)  # Set 60-second timeout
  1. Use the with statement to automatically close connections:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(('localhost', 9999))
    # Perform operations
  1. Handle reconnection:
def connect_with_retry(host, port, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((host, port))
            return sock
        except socket.error as e:
            if attempt == max_attempts - 1:
                raise
            time.sleep(2 ** attempt)  # Exponential backoff

Common Issues

In my teaching experience, students often encounter some issues. For example:

  1. "Why does my server say the port is occupied when I restart after closing?" This is because the TCP connection enters the TIME_WAIT state after closing. The solution is to add the following code:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  1. "Why does recv() sometimes not receive complete data?" This is because TCP is a streaming protocol, and data may be split into packets. I recommend handling it like this:
def recv_all(sock, length):
    data = b''
    while len(data) < length:
        more = sock.recv(length - len(data))
        if not more:
            raise EOFError('socket closed with %d bytes left to read' % (length - len(data)))
        data += more
    return data

Conclusion

Learning socket programming is like learning a new language; it may feel difficult at first, but once you master the basic concepts and common techniques, you can write all kinds of interesting network applications.

Have you ever thought about what you could create with this knowledge? Maybe a simple online game or a file transfer tool? I'm looking forward to seeing your creativity. If you encounter any problems during your learning process, feel free to leave a comment for discussion.

Remember, the most important thing in programming is not memorizing all the syntax but understanding the underlying principles. Once you understand how sockets work, you can better understand the entire internet world.

Let's continue exploring the fascinating world of Python network programming!

Python Network Programming: From Sockets to HTTP, Mastering the Essence of Network Communication
Previous
2024-11-13 13:07:02
Related articles