Hướng dẫn python socket

Bài viết giới thiệu căn bản về lập trình socket mà cụ thể là lập trình socket sử dụng TCP/IP bằng ngôn ngữ Python.

1. Socket là gì?

Một socket là một end-point của một liên kết giữa hai ứng dụng. Socket cho phép giao tiếp trong 1 tiến trình, giữa những tiến trình trên cùng 1 máy hoặc giữa nhiều máy với nhau.

Trong hệ thống mạng có rất nhiều ứng dụng bao gồm chương trình khách và chương trình chủ ở 2 hệ cuối khác nhau. Sau khi được kích hoạt, một tiến trình khách và chủ được tạo và mục đích của socket được sử dụng là để giúp 2 tiến trình này có thể truyền thông với nhau dễ dàng.

Socket được chia chủ yếu thành 2 loại:

  • Stream socket: Dựa trên giao thức TCP, chỉ thực hiện trên 2 tiến trình đã thiết lập kết nối. Giao thức này đảm bảo dữ liệu truyền đến nơi nhận 1 cách tin cậy và đúng tuần tự. Còn được gọi là socket hướng kết nối.
  • Datagram socket: Dựa trên giao thức UDP, không yêu cầu thiết lập kết nối. Giao thức này không đảm bảo dữ liệu truyền đến nơi nhận 1 cách tin cậy và toàn vẹn. Còn được gọi là socket hướng không kết nối.

*Trong phạm vi bài viết này mình chỉ để cập đến lập trình socket dùng TCP/IP (Stream socket)

Hướng dẫn python socket

2. Lập trình socket với TCP/IP

Các tiến trình mà muốn truyền thông với nhau thì sẽ gửi thông điệp thông qua các socket. Socket là cánh cửa của tiến trình ứng dụng và giao thức tầng transport (ở đây là TCP).

Để có thể tương tác với nhau và máy chủ có thể nhận liên lạc từ máy khách thì máy chủ phải luôn sẵn sàng. Điều này có 2 nghĩa, thứ nhất, giống như trường hợp của UDP, một tiến trình của máy chủ phải được chạy trước khi máy khách khởi tạo liên lạc đến. Thứ hai, chương trình chủ phải tạo ra 1 socket để sẵn sàng chấp nhận kết nối từ tiến trình khách.

Khi tiến trình chủ đã chạy, lúc này tiến trình khách sẽ tạo ra 1 socket TCP để có thể kết nối đến máy chủ. Trong khi máy khách đang tạo TCP socket, nó sẽ đặc tả địa chỉ IP, số cổng của tiến trình chủ.

Khi socket của tiến trình khách vừa được tạo, TCP  trên máy khách sẽ tiến hành thực hiện quá trình bắt tay 3 bước và thiết lập kết nối TCP tới máy chủ.

Trong quá trình bắt tay 3 bước, khi tiến trình chủ nhận thấy tiến trình khách, nó sẽ tự tạo ra 1 socket mới chỉ dành riêng cho tiến trình khách đó. Khi được máy khách gõ cửa, chương trình kích hoạt với phương thức accept(). Cuối quá trình bắt tay 3 bước, một kết nối TCP tồn tại giữa socket của máy khách và socket của máy chủ.

Hướng dẫn python socket

3. Module socket trong Python

Python cung cấp module socket giúp chúng ta dễ dàng thực hiện kết nối client server để giao tiếp với nhau.

Để có thể sử dụng được trước tiên ta phải import module socket vào chương trình

import socket

Tạo một socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

với

  • tham số đầu tiên là Address Family: kiểu thiết lập kết nối. Python hỗ trợ 3 dạng:
    • AF_INET: Ipv4
    • AF_INET6: Ipv6
    • AF_UNIX
  • tham số thứ hai là Socket Type: cách thiết lập giao thức
    • SOCK_STREAM: TCP
    • SOCK_DGRAM: UDP

Một số phương thức được sử dụng trong chương trình:

s.bind((HOST, PORT))

Đăng ký tên cho socket, ràng buộc địa chỉ vào socket

s.listen(2)

Cho socket đang lắng nghe tới tối đa 2 kết nối

client, addr = s.accept()

Khi một client gõ cửa, server chấp nhận kết nối và 1 socket mới được tạo ra. Client và server bây giờ đã có thể truyền và nhận dữ liệu với nhau

data = client.recv(1024)

Nhận gói dữ liệu

str_data = data.decode("utf8")

Phân tích gói dữ liệu vừa nhận

s.sendall(bytes(msg, "utf8"))

Gửi dữ liệu thông qua giao thức TCP
s.close() Đóng một kết nối

4. Chương trình demo

Server:

import socket

HOST = '127.0.0.1'  
PORT = 8000        

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(2)

while True:
    client, addr = s.accept()
    
    try:
        print('Connected by', addr)
        while True:
            data = client.recv(1024)
            str_data = data.decode("utf8")
            if str_data == "quit":
                break
            """if not data:
                break
            """
            print("Client: " + str_data)

            msg = input("Server: ")
                
    finally:
        client.close()

s.close()

Client:

import socket

HOST = '127.0.0.1'  
PORT = 8000        

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (HOST, PORT)
print('connecting to %s port ' + str(server_address))
s.connect(server_address)

try:
    while True:
        msg = input('Client: ')
        s.sendall(bytes(msg, "utf8"))

        if msg == "quit":
            break

        data = s.recv(1024)
        print('Server: ', data.decode("utf8"))
finally:
    s.close()

Lời kết

Mình học môn mạng máy tính và mong moi người góp ý với mình ở phần comment nha. Cảm ơn mọi người đã xem.