Ổ cắm mạng là điểm cuối của giao tiếp liên quá trình qua mạng máy tính. Thư viện chuẩn Python có một mô-đun có tên là
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
7 cung cấp giao diện mạng internet cấp thấp. Giao diện này phổ biến trên các ngôn ngữ lập trình khác nhau vì nó sử dụng các lệnh gọi hệ thống cấp hệ điều hànhĐể tạo socket, có một hàm tên là
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
7. Nó chấp nhận các đối số import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
9, import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
0 và import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
1 [xem tài liệu để biết chi tiết]. Để tạo ổ cắm TCP, bạn nên sử dụng import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
0 hoặc import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
1 cho import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
9 và import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
3 cho import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
4Đây là một ví dụ về ổ cắm Pythonimport socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
Nó trả về một đối tượng ổ cắm có các phương thức chính sau
5import socket s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.bind[['localhost', 50000]] s.listen[1] conn, addr = s.accept[] while 1: data = conn.recv[1024] if not data: break conn.sendall[data] conn.close[]
6import socket s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.bind[['localhost', 50000]] s.listen[1] conn, addr = s.accept[] while 1: data = conn.recv[1024] if not data: break conn.sendall[data] conn.close[]
7import socket s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.bind[['localhost', 50000]] s.listen[1] conn, addr = s.accept[] while 1: data = conn.recv[1024] if not data: break conn.sendall[data] conn.close[]
8import socket s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.bind[['localhost', 50000]] s.listen[1] conn, addr = s.accept[] while 1: data = conn.recv[1024] if not data: break conn.sendall[data] conn.close[]
9import socket s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.bind[['localhost', 50000]] s.listen[1] conn, addr = s.accept[] while 1: data = conn.recv[1024] if not data: break conn.sendall[data] conn.close[]
00import socket s = socket.socket[socket.AF_INET, socket.SOCK_STREAM] s.bind[['localhost', 50000]] s.listen[1] conn, addr = s.accept[] while 1: data = conn.recv[1024] if not data: break conn.sendall[data] conn.close[]
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
5, import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
6 và import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
7 dành riêng cho ổ cắm máy chủ. import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
8 dành riêng cho ổ cắm máy khách. import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
9 và import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
00 là chung cho cả hai loại. Đây là một ví dụ về máy chủ Echo từ tài liệuimport socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
Ở đây chúng tôi tạo một ổ cắm máy chủ, liên kết nó với một cổng localhost và 50000 và bắt đầu lắng nghe các kết nối đến. Để chấp nhận kết nối đến, chúng tôi gọi phương thức
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
7 sẽ chặn cho đến khi khách hàng mới kết nối. Khi điều này xảy ra, nó sẽ tạo một ổ cắm mới và trả về cùng với địa chỉ của máy khách. Sau đó, trong một chu kỳ vô hạn, nó đọc dữ liệu từ ổ cắm theo lô 1024 byte bằng phương thức import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
00 cho đến khi nó trả về một chuỗi rỗng. Sau đó, nó sẽ gửi lại tất cả dữ liệu đến bằng một phương thức thuận tiện import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
09 mà bên trong liên tục gọi import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
9. Và sau đó, nó chỉ cần đóng kết nối của máy khách. Ví dụ này chỉ có thể phục vụ một kết nối đến vì nó không gọi import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
7 trong một chu kỳMã phía máy khách trông đơn giản hơn
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
0Ở đây thay vì
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
5 và import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
6, nó chỉ gọi import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
8 và ngay lập tức gửi dữ liệu đến máy chủ. Sau đó, nó nhận lại 1024 byte, đóng ổ cắm và in dữ liệu đã nhậnTất cả các phương pháp ổ cắm đang chặn. Ví dụ, khi nó đọc hoặc ghi từ một ổ cắm, chương trình không thể làm gì khác. Một giải pháp khả thi là ủy quyền làm việc với khách hàng để tách các chủ đề. Tuy nhiên, việc tạo các luồng và chuyển ngữ cảnh giữa chúng không thực sự là một hoạt động rẻ tiền. Để giải quyết vấn đề này, có một cách gọi là cách làm việc không đồng bộ với socket. Ý tưởng chính là ủy thác việc duy trì trạng thái của ổ cắm cho một hệ điều hành và để nó thông báo cho chương trình khi có thứ gì đó cần đọc từ ổ cắm hoặc khi nó sẵn sàng để ghi.
Có rất nhiều giao diện cho các hệ điều hành khác nhau
- thăm dò ý kiến, epoll [linux]
- kqueue, kevent [BSD]
- chọn [đa nền tảng]
Tất cả chúng đều giống nhau, vì vậy hãy tạo một máy chủ bằng Python chọn. Đây là một ví dụ về Python
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
75import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
7Như bạn có thể thấy, có nhiều mã hơn trong máy chủ Echo đang chặn. Điều đó chủ yếu là do chúng tôi phải duy trì một tập hợp hàng đợi cho các danh sách ổ cắm khác nhau, tôi. e. viết, đọc và một danh sách riêng cho các ổ cắm bị lỗi
Tạo ổ cắm máy chủ trông giống nhau ngoại trừ một dòng.
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
76. Điều này được thực hiện để làm cho ổ cắm không bị chặn. Máy chủ này cao cấp hơn vì nó có thể phục vụ nhiều hơn một máy khách. Điểm chính là ở ổ cắm import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
77import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
1Ở đây, chúng tôi gọi
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
78 để yêu cầu HĐH kiểm tra các ổ cắm đã cho xem chúng đã sẵn sàng để viết, đọc hay có một số ngoại lệ tương ứng. Đó là lý do tại sao nó vượt qua ba danh sách ổ cắm để chỉ định ổ cắm nào được cho là có thể ghi, có thể đọc và ổ cắm nào cần được kiểm tra lỗi. Cuộc gọi này sẽ chặn chương trình [trừ khi đối số hết thời gian chờ được thông qua] cho đến khi một số ổ cắm được thông qua sẵn sàng. Tại thời điểm này, cuộc gọi sẽ trả về ba danh sách có ổ cắm cho các hoạt động được chỉ địnhSau đó, nó tuần tự lặp lại các danh sách đó và nếu có ổ cắm trong đó, nó sẽ thực hiện các hoạt động tương ứng. Khi có ổ cắm máy chủ trong
import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
79, điều đó có nghĩa là một máy khách mới đã đến. Do đó, nó gọi import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
7, thêm một ổ cắm được trả về vào import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
79 và thêm một import socket
s = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
s.bind[['localhost', 50000]]
s.listen[1]
conn, addr = s.accept[]
while 1:
data = conn.recv[1024]
if not data:
break
conn.sendall[data]
conn.close[]
12 cho các tin nhắn đến sẽ được gửi lại. Nếu có một ổ cắm khác trong đầu vào, thì một số tin nhắn đã đến và sẵn sàng để đọc để nó đọc chúng và đặt chúng vào hàng đợi tương ứngĐối với các ổ cắm có thể ghi, nó sẽ nhận các tin nhắn đang chờ xử lý [nếu có] và ghi chúng vào ổ cắm. Nếu có bất kỳ lỗi nào trong ổ cắm, nó sẽ xóa ổ cắm khỏi danh sách
Đây là cách socket hoạt động ở mức thấp hơn. Tuy nhiên, trong hầu hết các trường hợp, không cần triển khai logic ở mức thấp như vậy. Bạn nên sử dụng một số trừu tượng cấp cao hơn như Twisted, Tornado hoặc ZeroMQ, tùy thuộc vào tình huống.
Chúng tôi hoan nghênh bạn xem trang nghiên cứu điển hình của chúng tôi.
Tìm hiểu cách tích hợp máy chủ WebSocket được viết bằng aiohttp vào dự án Django hiện có trong bài viết của chúng tôi. Hoặc học cách viết một cuộc trò chuyện đơn giản