Python - Lập trình Socket

Xin chào các bạn future Python wizards! Hôm nay, chúng ta sẽ khám phá thế giới thú vị của lập trình socket. Đừng lo lắng nếu bạn là người mới bắt đầu; chúng ta sẽ bắt đầu từ những kiến thức cơ bản nhất và dần dần nâng cao. Cuối cùng của bài hướng dẫn này, bạn sẽ có thể tạo ra các ứng dụng mạng của riêng mình như một chuyên gia!

Python - Socket Programming

Sockets là gì?

Hãy tưởng tượng bạn đang cố gắng nói chuyện với một người bạn ở xa. Bạn cần một cách để gửi tin nhắn và nhận phản hồi của họ. Trong thế giới máy tính, sockets đóng vai trò này. Chúng giống như các线路 điện thoại cho phép các máy tính giao tiếp với nhau qua mạng.

Sockets là các điểm cuối của một liên kết giao tiếp hai chiều giữa hai chương trình chạy trên mạng. Chúng là cách bạn gửi tin nhắn giữa một client (như trình duyệt web) và một server (như một trang web).

Module socket của Python

Python làm cho lập trình socket trở nên dễ dàng với module socket tích hợp sẵn. Hãy bắt đầu bằng cách nhập nó:

import socket

Dòng đơn giản này cho phép chúng ta truy cập tất cả các chức năng socket cần thiết. Nó giống như mở hộp công cụ trước khi chúng ta bắt đầu xây dựng!

Phương thức của Socket Server

Khi chúng ta tạo một server, chúng ta cần sử dụng các phương thức cụ thể để thiết lập nó. Dưới đây là bảng các phương thức socket server phổ biến nhất:

Phương thức Mô tả
socket() Tạo một socket mới
bind() Gắn socket vào một địa chỉ và cổng cụ thể
listen() Đặt server vào chế độ lắng nghe
accept() Chấp nhận kết nối từ client

Hãy cùng xem chúng trong hành động với một ví dụ đơn giản:

import socket

# Tạo một đối tượng socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Gắn socket vào một địa chỉ và cổng cụ thể
server_socket.bind(('localhost', 12345))

# Lắng nghe các kết nối vào
server_socket.listen(1)

print("Server is listening...")

# Chấp nhận một kết nối
client_socket, address = server_socket.accept()
print(f"Connection from {address} has been established!")

# Đóng kết nối
client_socket.close()

Trong ví dụ này, chúng ta tạo một socket, gắn nó vào 'localhost' trên cổng 12345, bắt đầu lắng nghe, và sau đó chờ client kết nối. Khi một kết nối được thiết lập, chúng ta in một thông báo và sau đó đóng kết nối.

Phương thức của Socket Client

Bây giờ, hãy xem xét phía client. Dưới đây là các phương thức chính chúng ta sử dụng khi tạo một client:

Phương thức Mô tả
socket() Tạo một socket mới
connect() Kết nối với một socket từ xa tại địa chỉ chỉ định
send() Gửi dữ liệu đến socket đã kết nối
recv() Nhận dữ liệu từ socket đã kết nối

Dưới đây là một ví dụ client đơn giản:

import socket

# Tạo một đối tượng socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Kết nối với server
client_socket.connect(('localhost', 12345))

print("Connected to the server!")

# Đóng kết nối
client_socket.close()

Client này tạo một socket, kết nối với server (nếu server đang chạy), và sau đó đóng kết nối.

Python - Socket Server

Hãy mở rộng ví dụ server của chúng ta để thực sự làm một điều gì đó hữu ích:

import socket

def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 12345))
server_socket.listen(1)

print("Server is listening...")

while True:
client_socket, address = server_socket.accept()
print(f"Connection from {address} has been established!")

message = "Welcome to the server!"
client_socket.send(message.encode())

client_socket.close()

start_server()

Server này sẽ tiếp tục chạy, chấp nhận các kết nối, gửi tin nhắn chào mừng, và sau đó đóng kết nối.

Python - Socket Client

Bây giờ, hãy tạo một client có thể nhận tin nhắn từ server:

import socket

def start_client():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 12345))

message = client_socket.recv(1024).decode()
print(f"Message from server: {message}")

client_socket.close()

start_client()

Client này kết nối với server, nhận tin nhắn chào mừng, in nó ra, và sau đó đóng kết nối.

Chuyển file bằng Module Socket

Một ứng dụng thực tế của lập trình socket là chuyển file. Dưới đây là một ví dụ đơn giản về cách gửi một file từ client đến server:

Server:

import socket

def receive_file():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 12345))
server_socket.listen(1)

print("Server is waiting for file...")

client_socket, address = server_socket.accept()
print(f"Connection from {address} has been established!")

with open('received_file.txt', 'wb') as file:
while True:
data = client_socket.recv(1024)
if not data:
break
file.write(data)

print("File has been received successfully!")
client_socket.close()

receive_file()

Client:

import socket

def send_file():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 12345))

with open('file_to_send.txt', 'rb') as file:
data = file.read(1024)
while data:
client_socket.send(data)
data = file.read(1024)

print("File has been sent successfully!")
client_socket.close()

send_file()

Ví dụ này minh họa cách gửi một file từ client đến server sử dụng sockets.

Module socketserver của Python

Đối với các ứng dụng server phức tạp hơn, Python cung cấp module socketserver. Module này đơn giản hóa quá trình viết các server mạng. Dưới đây là một ví dụ đơn giản:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print(f"Received: {self.data.decode()}")
self.request.sendall("Message received".encode())

if __name__ == "__main__":
HOST, PORT = "localhost", 9999
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
print("Server is running...")
server.serve_forever()

Server này sử dụng module socketserver để tạo một TCP server rằng phản hồi lại bất kỳ tin nhắn nào nó nhận được.

Và đó là tất cả, các bạn! Chúng ta đã bao gồm các kiến thức cơ bản của lập trình socket trong Python, từ việc tạo ra các client và server đơn giản đến việc chuyển file và sử dụng module socketserver. Hãy nhớ rằng, thực hành là cách tốt nhất để trở nên thành thạo, vì vậy đừng ngần ngại thử nghiệm với các khái niệm này. Chúc các bạn may mắn trong việc编码!

Credits: Image by storyset