Hướng dẫn socket trong python

Python là ngôn ngữ cho phép chúng ta làm việc ở hai cấp độ truy cập của dịch vụ mạng. Trong bài viết này, Học viện Agile sẽ chia sẻ đến các bạn những kiến thức cơ bản về lập trình socket trong Python.

  • Socket là gì?
    • Một số thuộc tính của Socket:
  • Mô hình Lập trình Socket bằng Python
    • Chương trình demo Lập trình Socket bằng Python

Socket là gì?

Giữa hai chương trình chạy trên mạng cần có liên kết hai chiều để kết nối 2 ứng dụng với nhau. Điểm cuối, điểm đầu nút của liên kết song hướng (endpoint) được gọi là socket. Cụ thể, khi bạn viết một ứng dụng và cần tương tác với ứng dụng khác, chúng ta sẽ dựa vào mô hình client/server:

  • Server: ứng dụng có khả năng phục vụ, cung cấp cho bạn thông tin.
  • Client: ứng dụng gửi yêu cầu đến server.

Để yêu cầu được server thực hiện điều gì đó, client phải có khả năng kết nối đến server. Cơ chế kết nối này được trừu tượng hóa gọi là socket, tương tự như việc cắm dây điện vào ổ cắm. Server được coi là ổ cắm, Client là phích cắm. Một ổ cắm có thể cắm nhiều phích điện, tương tự việc một Server có thể kết nối và phục vụ cho nhiều Client. 

Hướng dẫn socket trong python

Socket được chia làm 2 loại chính là Steam Socket và Datagram Socket.

  • Steam Socket (dựa trên giao thức TCP): Việc truyền dữ liệu chỉ được thực hiện giữa 2 quá trình đã thiết lập kết nối. Steam socket đảm bảo dữ liệu truyền đi đáng tin cậy nhờ có cơ chế chống tắc nghẽn và cơ chế quản lý luồng lưu thông trên mạng.
  • Datagram Socket (dựa trên giao thức UDP): Việc truyền dữ liệu không cần có thiết lập kết nối giữa 2 quá trình. Trái ngược với TCP, truyền dữ liệu theo giao thức UDP kém tin cậy, có thể sai trình tự và bị lặp lại. Tuy nhiên cơ chế của Datagram đơn giản hơn nên có tốc độ nhanh, thường được ứng dụng trong các ứng dụng chat hoặc game online.

Một số thuộc tính của Socket:

Khái niệm Miêu tả
Domain (vùng) Vùng dùng xác định hạ tầng mạng, nơi diễn ra giao tiếp của socket. Vùng giao tiếp thông dụng nhất hiện nay là AF_INET. AF_UNIX chỉ dùng trong giao tiếp cục bộ nhưng trong thực tế ít được sử dụng. Ngoài ra chúng ta có AF_IPX, AF_ISO và AF_NS
Type (kiểu) Với mỗi vùng của domain, bạn có nhiều cách để giao tiếp: SOCK_DGRAM (giao tiếp một chiều) và SOCK_STREAM (giao tiếp 2 chiều)
Protocol (giao thức) Là cách quy ước gửi nhận dữ liệu giữa hai hay nhiều máy tính trong mạng. Mặc định là 0, sử dụng để nhận diện một biến thể của giao thức bên trong domain 

Mô hình Lập trình Socket bằng Python

Mô tả mô hình

  1. Chúng ta mở một socket – socket() để tạo ổ cắm socket cho Server.  Đây là quá trình Hệ điều hành phân bổ tài nguyên, chuẩn bị kết nối. Bạn cần chỉ định tên hoặc số hiệu port cho socket để Client biết đến ổ cắm của Server.
  2. Chúng ta liên kết máy chủ với host hoặc một máy và một port – bind(). 
  3. Server sẽ bắt đầu lắng nghe các kết nối từ Client đưa đến trên port – listen().
  4. Một yêu cầu kết nối được gửi từ client tới server – connect().Server chấp nhận yêu cầu của client, kết nối từ đó được thiết lập – accept()
  5. Đã có thể gửi và nhận tin – read() / write() tương tự dùng lệnh read/write để đọc ghi trên tập tin.  Socket dựa vào số mô tả (socket descriptor) để xác định cần đọc ghi cho hàm read/write.
  6. Đóng kết nối – close()

Trong phạm vi bài viết, Học viện Agile sẽ tập trung vào Steam Socket (dựa trên giao thức TCP)

Socket Module trong Python

Trong Python, chúng ta sử dụng hàm socket.socket() trong Socket Module với cú pháp chung:

Chi tiết tham số:

socket_family (Address Family, hay còn gọi là kiểu thiết lập kết nối)
  • AF_UNIX 
  • AF_INET (Ipv4) hoặc AF_INET6 (Ipv6)
  • AF_IPX (vùng giao thức IPX mạng Novell)
  • AF_ISO (chuẩn giao thức ISO)
  • AF_NS (giao thức Xerox Network System)
socket_type (cách thiết lập giao thức)
  • SOCK_STREAM (giao thức TCP)
  • SOCK_DGRAM (giao thức UDP)

Ngoài ra, chúng ta còn có thêm một số phương thức:

Phương thức Ý nghĩa
s.bind((HOST, PORT)) Đăng ký tên, gán địa chỉ vào socket
s.close() Đóng kết nối
s.listen(2)  Socket lắng nghe tới >= 2 kết nối
data = client.recv(1024) Nhận dữ liệu
client, addr = s.accept()  Client gõ cửa, server chấp nhận và tạo ra một socket mới. Client và server đã có thể nhận và truyền dữ liệu.
str_data = data.decode(“utf8”) Phân tích dữ liệu đã nhận
s.sendall(bytes(msg, “utf8”)) Gửi dữ liệu trên Steam Socket (thông qua giao thức TCP)

Chương trình demo Lập trình Socket bằng Python

Lập trình Socket trên Server

Hướng dẫn socket trong python

Lập trình Socket trên Client

Hướng dẫn socket trong python

Xử lý kết nối đồng thời nhiều Client

Cách xử lý tuần tự phía trên sẽ không phù hợp khi có nhiều Client cùng kết nối đến một Server. Để xử lý đồng thời kết nối của nhiều Client, bạn có thể sử dụng lệnh fork() để tạo trình con mới hoạt động độc lập với Server và phục vụ Client theo cách riêng của nó. Server hoàn toàn tự do để tiếp nhận kết nối khác.

Một cách nữa để xử lý kết nối đồng thời nhiều Client là sử dụng cách tạo tuyến thread. Lưu ý: tuyến ít khi được dùng trong UNIX và LINUX.

Hy vọng rằng bài viết đã đem đến thông tin bổ ích cho các bạn về lập trình socket bằng Python. Ngoài những hiểu biết về ngôn ngữ lập trình, để có tư duy phát triển phần mềm linh hoạt, rút ngắn thời gian đưa sản phẩm đến tay người dùng, các bạn nên tham khảo thêm về Agile Software Development – phương pháp phát triển phần mềm linh hoạt. Nhờ khả năng vận hành tốt, đáp ứng đa dạng nhu cầu, đem lại hiệu quả và năng suất cao, Agile đang là sự lựa chọn hàng đầu của khách hàng, nhà phát triển, công ty phần mềm.