Luồng ổ cắm Python

Ngày nay, bất kỳ ai có kết nối Internet đủ nhanh đều có thể xem phim độ phân giải cao hoặc thực hiện cuộc gọi video qua Internet. Điều này có thể thực hiện được nhờ một công nghệ gọi là phát trực tuyến

Truyền trực tuyến là việc truyền liên tục các tệp âm thanh hoặc video từ máy chủ đến máy khách. Nói một cách đơn giản hơn, phát trực tuyến là điều xảy ra khi người tiêu dùng xem TV hoặc nghe podcast trên các thiết bị kết nối Internet. Với tính năng phát trực tuyến, tệp phương tiện đang được phát trên thiết bị khách được lưu trữ từ xa và được truyền vài giây một lần qua Internet

Trong bối cảnh hiện tại, tính năng phát trực tuyến video đã trở nên phổ biến hơn do đại dịch nhằm giao lưu, trao đổi, kết nối, học hỏi, v.v.

Khách quan

Xây dựng ứng dụng phát video trực tiếp không có âm thanh bằng lập trình socket với python

Lập trình Socket là gì?

Ổ cắm và API ổ cắm được sử dụng để gửi tin nhắn qua mạng. Họ cung cấp một hình thức giao tiếp giữa các quá trình (IPC). Mạng có thể là mạng cục bộ, hợp lý với máy tính hoặc mạng được kết nối vật lý với mạng bên ngoài, có kết nối riêng với các mạng khác. Ví dụ phổ biến nhất là internet

Loại ứng dụng ổ cắm phổ biến nhất là ứng dụng máy khách-máy chủ, trong đó một bên đóng vai trò là máy chủ và chờ kết nối từ máy khách, đây là loại ứng dụng phát video trực tiếp mà chúng tôi sẽ xây dựng

Loại ổ cắm nào phù hợp với mục tiêu của chúng tôi?

Loại ổ cắm phù hợp nhất là ổ cắm TCP dưới dạng Giao thức điều khiển truyền dẫn (TCP)

  • Đáng tin cậy. các gói bị rơi trong mạng được phát hiện và truyền lại bởi người gửi
  • Có phân phối dữ liệu theo thứ tự. dữ liệu được đọc bởi ứng dụng của bạn theo thứ tự được viết bởi người gửi

Luồng ổ cắm TCP

Hãy bắt đầu xây dựng ứng dụng phát video trực tiếp

Yêu cầu -

  • IDE. Máy tính xách tay Jupyter
  • Ngôn ngữ. con trăn

Theo luồng TCP, chúng tôi yêu cầu hai tệp khác nhau, một cho máy khách và một cho máy chủ. Vì vậy, có một số thiết lập cơ bản cần thiết cho cả hai và trừ khi được chỉ định, không có sự khác biệt như vậy

Bước 1. Cài đặt và nhập các thư viện sau vào cả hai tệp

Bạn có thể cần phải cài đặt cụ thể opencv-python và imutils để nhập chúng

  • ổ cắm. Để lấy mô-đun ổ cắm từ python
    cv2. Để nhập mô-đun Thị giác máy tính từ python
    pickle. để tuần tự hóa và hủy tuần tự hóa các cấu trúc đối tượng python.
    cấu trúc. để chuyển đổi các kiểu dữ liệu gốc của Python chẳng hạn như chuỗi và số thành chuỗi byte và ngược lại
    imutils. Thao tác xử lý ảnh

Bước 2. Tạo ổ cắm

Tạo một ổ cắm phía Máy khách

Tạo một ổ cắm phía máy chủ

Bước 3. Truyền phát video

Ở phía máy chủ, chúng tôi sử dụng

s.listen(5)
4 làm nó và chờ kết nối đến. Khi một máy khách kết nối, nó trả về một đối tượng ổ cắm mới đại diện cho kết nối và một bộ chứa địa chỉ của máy khách. Tuple sẽ chứa
s.listen(5)
5 cho các kết nối IPv4 hoặc
s.listen(5)
6 cho IPv6. Sau đó, chúng tôi phải tuần tự hóa khung thành byte, đóng gói dữ liệu được tuần tự hóa và gửi dữ liệu này và in thông báo lỗi trong trường hợp xảy ra lỗi và cuối cùng hiển thị khung video

Máy chủ chấp nhận yêu cầu của khách hàng

Máy khách tạo một đối tượng ổ cắm, kết nối với máy chủ và gọi

s.listen(5)
7 để đọc phản hồi của máy chủ. Ở phía máy khách, chúng tôi nhận được các khung dữ liệu để phát trực tuyến video nhưng ở dạng gói dữ liệu mà chúng tôi phải giải nén và hủy tuần tự hóa rồi hiển thị khung video thực tế

Phía khách hàng

Kết quả

Ảnh chụp màn hình từ luồng video

Phần kết luận

Do đó, theo cách này, chúng ta có thể tạo một ứng dụng phát video trực tiếp không có âm thanh, có thể được sử dụng cho các mục đích như giám sát hoặc có thể học nhóm mà không bị quấy rầy, v.v.

Chào mừng bạn đến với hướng dẫn về ổ cắm với Python 3. Chúng tôi có rất nhiều thứ để trang trải, vì vậy hãy bắt đầu ngay. Thư viện

s.listen(5)
4 là một phần của thư viện chuẩn, vì vậy bạn đã có nó

import socket

# create the socket
# AF_INET == ipv4
# SOCK_STREAM == TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Biến

s.listen(5)
5 là ổ cắm TCP/IP của chúng tôi. AF_INET liên quan đến họ hoặc miền, nó có nghĩa là ipv4, trái ngược với ipv6 với AF_INET6. SOCK_STREAM có nghĩa là nó sẽ là một ổ cắm TCP, đây là loại ổ cắm của chúng tôi. TCP có nghĩa là nó sẽ được định hướng kết nối, trái ngược với không kết nối

Được rồi, vậy ổ cắm là gì?

Một ổ cắm sẽ được gắn với một số cổng trên một số máy chủ. Nói chung, bạn sẽ có loại thực thể hoặc chương trình máy khách hoặc máy chủ

Trong trường hợp của

s.listen(5)
6, bạn sẽ liên kết một ổ cắm với một số cổng trên máy chủ (localhost). Trong trường hợp của một
s.listen(5)
7, bạn sẽ kết nối một ổ cắm với máy chủ đó, trên cùng một cổng mà mã phía máy chủ đang sử dụng

Hãy tạo mã này cho đến nay phía máy chủ của chúng tôi

s.bind((socket.gethostname(), 1234))

Đối với ổ cắm IP, địa chỉ mà chúng tôi liên kết là một bộ tên máy chủ và số cổng

Bây giờ chúng ta đã hoàn thành việc đó, hãy lắng nghe các kết nối đến. Chúng tôi chỉ có thể xử lý một kết nối tại một thời điểm nhất định, vì vậy chúng tôi muốn cho phép một số loại hàng đợi, chỉ trong trường hợp chúng tôi gặp sự cố nhẹ. Nếu ai đó cố gắng kết nối khi hàng đợi đã đầy, họ sẽ bị từ chối

Hãy xếp hàng 5 người

s.listen(5)

Và bây giờ, chúng ta chỉ lắng nghe

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

Mã đầy đủ cho

s.listen(5)
8

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

Bây giờ chúng ta cần tạo mã của khách hàng

import socket

# create the socket
# AF_INET == ipv4
# SOCK_STREAM == TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
0

Bây giờ, vì đây là khách hàng, chứ không phải là

s.listen(5)
9, chúng ta sẽ chuyển sang
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
0

import socket

# create the socket
# AF_INET == ipv4
# SOCK_STREAM == TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3

Theo nghĩa truyền thống hơn về máy khách và máy chủ, bạn sẽ không thực sự có máy khách và máy chủ trên cùng một máy. Nếu bạn muốn có hai chương trình nói chuyện với nhau cục bộ, bạn có thể làm điều này, nhưng thông thường, máy khách của bạn sẽ có nhiều khả năng kết nối với một số máy chủ bên ngoài, sử dụng địa chỉ IP công cộng của nó, không phải

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
1. Thay vào đó, bạn sẽ chuyển chuỗi IP

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 đầy đủ cho đến thời điểm này

import socket

# create the socket
# AF_INET == ipv4
# SOCK_STREAM == TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
6

Được rồi, bây giờ chúng tôi chỉ chạy cả hai. Đầu tiên, hãy chạy máy chủ của chúng tôi

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
3

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
4

Trên máy chủ của chúng tôi, chúng ta sẽ thấy

import socket

# create the socket
# AF_INET == ipv4
# SOCK_STREAM == TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
9

Tuy nhiên, khách hàng của chúng tôi chỉ thoát sau đó vì nó đã hoàn thành công việc của mình

Vì vậy, chúng tôi đã tạo kết nối và điều đó thật tuyệt, nhưng chúng tôi thực sự muốn gửi tin nhắn và/hoặc dữ liệu qua lại. làm sao chúng ta làm việc đó bây giờ?

Ổ cắm của chúng tôi có thể dữ liệu

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
5 và
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
6. Những phương pháp xử lý dữ liệu xử lý trong bộ đệm. Bộ đệm xảy ra trong khối dữ liệu có kích thước cố định. Hãy xem điều đó trong hành động

Bên trong

s.listen(5)
8, hãy thêm

s.listen(5)
3

Vào vòng lặp

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
8 của chúng tôi, vì vậy mã đầy đủ của chúng tôi cho
s.listen(5)
8 trở thành

s.bind((socket.gethostname(), 1234))
0

Vì vậy, chúng tôi đã gửi một số dữ liệu, bây giờ chúng tôi muốn nhận nó. Vì vậy, trong

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi, chúng tôi sẽ làm

s.bind((socket.gethostname(), 1234))
1

Điều này có nghĩa là ổ cắm của chúng tôi sẽ cố gắng nhận dữ liệu, với kích thước bộ đệm là 1024 byte mỗi lần

Sau đó, hãy làm điều gì đó cơ bản với dữ liệu chúng tôi nhận được, chẳng hạn như in nó ra

s.bind((socket.gethostname(), 1234))
2

Thật tuyệt, mã

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 đầy đủ của chúng tôi hiện đã có

s.bind((socket.gethostname(), 1234))
3

Bây giờ, hãy chạy cả

s.listen(5)
8 và sau đó là
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2. Chương trình
s.listen(5)
8 của chúng tôi

s.bind((socket.gethostname(), 1234))
4

Trong khi

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi hiện đang hiển thị

s.bind((socket.gethostname(), 1234))
5

Và nó thoát. Được rồi, vậy hãy điều chỉnh bộ đệm đó một chút, thay đổi

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2
while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
6 thành 8 byte mỗi lần

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.bind((socket.gethostname(), 1234))
6

Bây giờ, chạy lại

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2, và thay vào đó, bạn sẽ thấy một cái gì đó giống như

s.bind((socket.gethostname(), 1234))
7

Không trông thật nóng bỏng. Vì vậy, bạn có thể nhận ra rằng thêm tối đa 8 ký tự theo nghĩa đen, vì vậy mỗi byte là một ký tự. Tại sao không. quay lại 1024? . Tại sao lại làm việc trong bộ đệm?

Tại một số thời điểm, bất kể bạn đặt số lượng nào, nhiều ứng dụng sử dụng ổ cắm cuối cùng sẽ muốn gửi một lượng byte vượt xa kích thước bộ đệm. Thay vào đó, có lẽ chúng ta cần xây dựng chương trình của mình từ đầu để thực sự chấp nhận toàn bộ thông báo trong các đoạn của bộ đệm, ngay cả khi thường chỉ có một đoạn. Chúng tôi làm điều này chủ yếu để quản lý bộ nhớ. Các tính toán tùy thuộc vào ứng dụng có thể khác nhau và bạn có thể tự do chơi với kích thước bộ đệm sau này. Điều duy nhất tôi có thể chắc chắn hứa là. bạn cần lập kế hoạch ngay từ đầu để xử lý các giao tiếp theo khối

Đối với khách hàng của chúng tôi, làm thế nào chúng tôi có thể làm điều này? . Dữ liệu sẽ đến dưới dạng luồng, vì vậy, thực sự, việc xử lý việc này đơn giản như thay đổi tệp

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi thành

s.bind((socket.gethostname(), 1234))
8

Vì vậy, hiện tại, chúng tôi sẽ nhận dữ liệu này và in nó thành từng khối. Nếu chúng ta chạy

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 bây giờ, chúng ta sẽ thấy

s.bind((socket.gethostname(), 1234))
9

Bạn cũng nên lưu ý rằng ________ 72 của chúng tôi không còn tồn tại. Kết nối này hiện vẫn mở. Điều này là do vòng lặp

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
8 của chúng tôi. Chúng tôi có thể sử dụng
import socket

# create the socket
# AF_INET == ipv4
# SOCK_STREAM == TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
05 trên một ổ cắm để đóng nó nếu muốn. Chúng tôi có thể làm điều này trên máy chủ hoặc trên máy khách. hoặc cả hai. Có lẽ nên chuẩn bị cho trường hợp kết nối bị ngắt hoặc bị đóng vì bất kỳ lý do gì. Ví dụ: chúng tôi có thể đóng kết nối sau khi gửi tin nhắn của mình trên máy chủ

s.listen(5)
8

s.listen(5)
0

Tuy nhiên, nếu chúng tôi chạy cái này, chúng tôi sẽ thấy

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2 của chúng tôi sau đó gửi thư rác ra một loạt hư vô, bởi vì dữ liệu mà nó nhận được, không có gì. Nó trống rỗng. 0 byte, nhưng chúng tôi vẫn yêu cầu nó in ra những gì nó nhận được, ngay cả khi không có gì. Chúng tôi có thể khắc phục điều đó

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.listen(5)
1

Vì vậy, bây giờ chúng tôi đang xem qua toàn bộ thông báo. Khi chúng tôi kết thúc, điều mà chúng tôi đang chú ý bằng cách nhận 0 byte, chúng tôi sẽ ngắt và sau đó trả lại tin nhắn. Điều này sau đó kết thúc

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2. Bây giờ, khách hàng có thể muốn duy trì kết nối. Làm thế nào chúng ta có thể làm điều đó?

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.listen(5)
2

Tất nhiên, có lẽ một lần nữa chúng ta nên đảm bảo rằng

import socket

# create the socket
# AF_INET == ipv4
# SOCK_STREAM == TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
32 có nội dung gì đó trước khi chúng ta in nó ra

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")
2

s.listen(5)
3

Điều này hoạt động, nhưng chúng tôi có vấn đề. Điều gì xảy ra khi chúng tôi ngừng đóng ổ cắm máy khách ở phía máy chủ? . Tại sao lại thế này?

TCP là một giao tiếp *stream*. vậy làm thế nào để chúng ta thực sự biết khi nào một tin nhắn đang thực sự xảy ra? . Có nhiều cách để chúng ta có thể làm điều này. Một cách phổ biến là sử dụng một loại tiêu đề luôn dẫn đầu thông điệp của chúng tôi. Chúng tôi cũng có thể sử dụng một số loại chân trang, nhưng điều này có thể gây rắc rối nếu ai đó tìm hiểu về phương pháp của chúng tôi

Làm cách nào để truyền phát video bằng socket Python?

Cách gửi âm thanh và video bằng lập trình socket trong Python .
vid = cv2. VideoCapture(tên tệp) FPS = vid. nhận được (cv2. .
nếu khung hình/giây>FPS. TS+=0. 001 yêu tinh khung hình/giây
người thừa hành. submit(audio_stream) # để tạo và gửi luồng trình thực thi dữ liệu âm thanh

Ổ cắm luồng là gì?

Giao diện ổ cắm luồng xác định dịch vụ hướng kết nối đáng tin cậy . Dữ liệu được gửi không có lỗi hoặc trùng lặp và được nhận theo thứ tự như khi gửi. Kiểm soát luồng được tích hợp, để tránh tràn dữ liệu. Không có ranh giới nào được áp đặt trên dữ liệu; .

STREAMing có sử dụng ổ cắm không?

Ổ cắm luồng cung cấp luồng dữ liệu không có ranh giới bản ghi . một luồng byte có thể là hai chiều (ứng dụng song công hoàn toàn. nó có thể truyền và nhận qua ổ cắm). Các luồng có thể được dựa vào để cung cấp dữ liệu theo trình tự, không trùng lặp.

Ổ cắm Sock_stream trong Python là gì?

SOCK_STREAM. Cung cấp các luồng byte hai chiều, có trình tự với cơ chế truyền dữ liệu luồng . Loại ổ cắm này truyền dữ liệu trên cơ sở đáng tin cậy, theo thứ tự và có khả năng vượt trội. Trong miền UNIX, loại ổ cắm SOCK_STREAM hoạt động giống như một đường ống.