Ổ cắm trò chuyện Python

Xin chào mọi người, hôm nay chúng ta sẽ tạo một phòng trò chuyện thực sự đơn giản trong Python 3 với sự trợ giúp của các mô-đun tích hợp socket và threading

Ứng dụng trò chuyện của chúng tôi sẽ bao gồm một máy chủ và nhiều máy khách. Các máy khách sẽ thiết lập kết nối ổ cắm với máy chủ. Để kết nối ổ cắm hoạt động, cả máy chủ và máy khách cần phải ở trên cùng một máy hoặc trong cùng một mạng. Vì vậy, phòng trò chuyện sẽ hoạt động trên mạng LAN (Mạng cục bộ)

Hiểu về ổ cắm Python

Trước khi nhảy vào mã, chúng ta cần hiểu cách thức hoạt động của các ổ cắm. Không cần thiết phải biết cách thức hoạt động của các ổ cắm bên trong, thật thú vị khi biết rằng mô-đun ổ cắm python sử dụng thư viện ổ cắm C để trao đổi dữ liệu trên mạng. Về cơ bản, một máy chủ socket cần được khởi tạo, sau đó máy khách sẽ kết nối trực tiếp với máy chủ. Khi kết nối được thiết lập, một ổ cắm có thể vừa nghe vừa gửi tin nhắn, nếu một ổ cắm đang gửi và ổ cắm kia đang nghe, chúng ta sẽ có thể trao đổi dữ liệu giữa chúng

Bước 1. Mã hóa máy chủ

Khi bạn đã tạo tệp

my_socket.listen()
client, client_address = my_socket.accept()
8 của mình, chúng ta có thể bắt đầu mã hóa

Đầu tiên, chúng tôi sẽ nhập mô-đun chúng tôi cần

import socket

Sau đó, hãy tạo đối tượng socket của chúng ta

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

my_socket.listen()
client, client_address = my_socket.accept()
9 và
message = client.recv(1024) #bytes
print(message.decode())
0 chỉ là các hằng số được định nghĩa trong module socket để chọn loại socket mà chúng ta muốn, bạn không cần hiểu ý nghĩa của chúng để sử dụng chúng

Bây giờ ổ cắm đã được tạo, chúng ta có thể liên kết nó với một cổng và tùy chọn một địa chỉ. Chúng tôi tạo hai hằng số có tên là

message = client.recv(1024) #bytes
print(message.decode())
1 và
message = client.recv(1024) #bytes
print(message.decode())
2 để giữ cổng và địa chỉ chúng tôi sẽ sử dụng. Hiện tại, chúng tôi để địa chỉ là
message = client.recv(1024) #bytes
print(message.decode())
3, vì chúng tôi không biết địa chỉ của khách hàng sẽ là gì

________số 8

Bây giờ ổ cắm của chúng tôi đã sẵn sàng, chúng tôi có thể bắt đầu lắng nghe kết nối. Sau đó, chúng ta cần chấp nhận kết nối đến

my_socket.listen()
client, client_address = my_socket.accept()

Phương thức listen() chỉ cho phép các kết nối đến. Phương thức accept() trả về một bộ, phần tử đầu tiên là kết nối, bây giờ chúng ta sẽ sử dụng nó để tương tác với máy khách và phần tử thứ hai là một bộ chứa địa chỉ IP của máy khách cũng như cổng được sử dụng (có thể là

Bây giờ chúng tôi đã sẵn sàng để bắt đầu nghe tin nhắn từ khách hàng

message = client.recv(1024) #bytes
print(message.decode())

Phương thức recv() chỉ nhận một đối số không tùy chọn, kích thước bộ đệm, đó là dung lượng tối đa có sẵn để nhận tin nhắn. Đừng quên rằng phương thức này trả về một đối tượng byte và vì vậy bạn cần giải mã nó thành một chuỗi

OK, vậy bây giờ chúng ta sẽ hoàn thành với tập lệnh máy chủ cơ bản nhất có thể và tập lệnh máy khách thậm chí còn đơn giản hơn, bạn sẽ thấy. Ngay trước khi chuyển sang mã máy khách, hãy đảm bảo rằng chúng ta có cùng mã máy chủ, nếu bạn làm theo hướng dẫn này tốt, mã của bạn sẽ trông giống như thế

import socket
1

Bước 2. Mã hóa khách hàng

Tập lệnh máy khách gần giống như tập lệnh máy chủ, ngoại trừ thay vì lắng nghe kết nối và tin nhắn, chúng tôi thực sự sẽ kết nối và gửi tin nhắn

Đầu tiên, nhập mô-đun và tạo đối tượng ổ cắm của chúng tôi

import socket
2

Bây giờ chúng ta cần xác định cổng và địa chỉ của máy chủ, nếu bạn đang sử dụng cùng cổng với tôi, thì đó phải là

message = client.recv(1024) #bytes
print(message.decode())
4. Đối với địa chỉ, bạn chỉ cần nhập địa chỉ của máy chủ, nếu bạn đang chạy máy chủ và máy khách trên cùng một máy tính, thì địa chỉ máy chủ phải là
message = client.recv(1024) #bytes
print(message.decode())
5, nếu không thì chỉ cần tìm địa chỉ IP của máy chủ (Tôi sẽ không giải thích

import socket
5

Sau đó, chúng ta có thể kết nối với máy chủ

import socket
6

Bây giờ chúng tôi đã sẵn sàng để gửi tin nhắn. Chỉ cần gõ vào

import socket
7

Đừng quên mã hóa chuỗi thành byte, như chúng ta đã thấy trước đây, socket trao đổi byte, không phải chuỗi

Vì vậy, bây giờ tập lệnh máy khách của bạn sẽ trông giống như thế

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
0

Bây giờ bạn có thể sử dụng tập lệnh, khởi động tập lệnh máy chủ và khi nó bắt đầu khởi chạy tập lệnh máy khách, nếu mọi thứ diễn ra suôn sẻ, bạn sẽ thấy thông báo bạn đã chọn, được hiển thị trong bảng điều khiển của máy chủ bảng điều khiển

Cải thiện bản demo cơ bản của chúng tôi

Bây giờ có lẽ bạn đã thử nghiệm bản demo nhỏ của chúng tôi và có thể bạn đang tự nhủ rằng đây không giống một phòng chat. Và như bạn đang nói, đây chỉ là một bản demo để hiểu các ổ cắm, bây giờ chúng tôi thực sự có thể triển khai phòng trò chuyện nhỏ của mình

Đầu tiên, vì đây là một cuộc trò chuyện, nên chúng tôi có thể sẽ cần gửi nhiều tin nhắn chứ không chỉ một tin nhắn, vì vậy chúng tôi sẽ chỉnh sửa tập lệnh máy chủ của mình để nghe mãi mãi và trong ứng dụng khách, chúng tôi sẽ cho phép người dùng nhập một số

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1

Như bạn có thể thấy, tôi đã thêm một vòng lặp vô hạn để không bao giờ ngừng nghe tin nhắn. Bây giờ hãy làm việc trên client script

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2

Và ở đây, như bạn có thể thấy, người dùng hiện có thể nhập tin nhắn mà anh ấy muốn gửi và tôi cũng đã thêm một vòng lặp vô hạn ở đây. Tôi khuyến khích bạn thử mã này để thấy rằng nó hoạt động

Bước 3. Cho phép khách hàng của chúng tôi nhận được

OK, bây giờ chúng ta có thể gửi nhiều tin nhắn đến máy chủ, nhưng còn việc nhận tin nhắn từ máy chủ thì sao?

Vì vậy, chúng tôi sẽ cần lắng nghe cả đầu vào của người dùng và lắng nghe thông báo của máy chủ cùng một lúc, chúng tôi có thể làm điều đó như thế nào?

Một trong những giải pháp đơn giản nhất là sử dụng mô-đun tích hợp luồng python, với điều đó, chúng tôi sẽ có thể chạy nhiều luồng cùng một lúc, tôi sẽ không đi sâu vào chi tiết ở đây, chỉ cần xem các luồng như . Nếu bạn không biết cách thức hoạt động của các luồng, tôi khuyến khích bạn tìm thêm thông tin về chúng vì nó thực sự hữu ích trong mạng và lập trình nói chung

Bây giờ chúng tôi biết cách giải quyết vấn đề, chúng tôi cần mô-đun luồng, vì vậy hãy nhập nó

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3

Bây giờ chúng ta cần xác định hai hàm, một để nghe và một để gửi. Đối với phần gửi, chúng ta chỉ cần đặt vòng lặp while của mình vào một hàm, đại loại như thế này

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
4

Và chức năng nghe sẽ không phức tạp hơn

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5

Khi chúng tôi có hai chức năng của mình, bây giờ chúng tôi có thể tạo hai luồng, một luồng cho mỗi chức năng và bắt đầu chúng. Các luồng thực sự đơn giản để sử dụng, chúng ta chỉ cần tạo hai đối tượng luồng và chỉ định chức năng mà chúng sẽ thực thi

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
6

Chúng tôi chỉ cần bắt đầu chúng và đó là tất cả cho khách hàng bây giờ

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
7

Bạn có thể thử chạy tập lệnh máy khách và bạn sẽ không thấy bất kỳ sự khác biệt nào, đó là vì chúng tôi chưa yêu cầu máy chủ gửi bất kỳ tin nhắn nào, vì vậy hãy bắt tay vào việc đó. Để đơn giản, chúng ta sẽ làm cho máy chủ gửi một thứ gì đó mỗi khi nhận được tin nhắn, đại loại như thế

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
8

Bây giờ bạn có thể gửi tin nhắn và nhận phản hồi từ máy chủ. Như mọi khi, trước khi bắt đầu bước tiếp theo, hãy đảm bảo rằng chúng ta làm việc với cùng một mã

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
9

Và khách hàng

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
0

Bước 4. Thêm nhiều hơn một khách hàng

OK, vậy bây giờ chúng ta có thể kết nối với máy chủ bằng ứng dụng khách, chúng ta có thể gửi và nhận tin nhắn từ máy chủ, chúng ta gần như đã hoàn tất, nhưng, không phải một cuộc trò chuyện bao gồm nhiều người sao?

Vì vậy ban đầu chúng ta có thể chỉ nghĩ rằng để tạo một chat thì chỉ cần bắt đầu nhiều client, nhưng sau khi thử nghiệm phương pháp này, bạn sẽ hiểu rằng trong một chat, client cần phải tương tác với các client khác chứ không chỉ tương tác với nhau. . Để giải quyết vấn đề này, chúng tôi sẽ cần giữ một danh sách tất cả các máy khách được kết nối và mỗi khi ai đó gửi tin nhắn, chúng tôi sẽ gửi tin nhắn này cho tất cả các máy khách trong danh sách. Máy chủ của chúng tôi sẽ truyền tin nhắn từ khách hàng này sang khách hàng khác

Bước đầu tiên là có thể xử lý nhiều kết nối, như bạn có thể thấy trong mã, phương thức accept() chỉ được gọi một lần, nghĩa là chúng ta chỉ có thể nhận một kết nối, hãy thay đổi điều đó và chúng ta sẽ viết mã

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
1

Bây giờ chúng ta có thể thêm ứng dụng khách vào danh sách phát, trước tiên chúng ta cần tạo danh sách (ngoài chức năng)

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
2

Và nối ứng dụng khách vào danh sách (trong vòng lặp)

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
3

Và điều cuối cùng, chúng ta cần thiết lập một chuỗi sẽ lắng nghe tin nhắn từ khách hàng

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
4

Như bạn có thể thấy, chúng tôi chưa mã hóa chức năng này, chúng tôi sẽ thực hiện điều đó sau một phút, trước khi đảm bảo rằng chúng tôi có chức năng tương tự

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
5

OK, bây giờ chúng ta chắc chắn có cùng mã, vì vậy hãy tạo hàm

message = client.recv(1024) #bytes
print(message.decode())
6. Chức năng này cần tạo một chuỗi dành riêng cho ứng dụng khách này sẽ nghe tin nhắn và phát chúng

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
6

Bây giờ chúng ta cần triển khai chức năng

message = client.recv(1024) #bytes
print(message.decode())
7 của mình

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
7

Và chức năng cuối cùng để viết,

message = client.recv(1024) #bytes
print(message.decode())
8 sẽ chỉ gửi tin nhắn cho mọi khách hàng trong danh sách quảng bá

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
8

Bây giờ chúng ta có thể chạy một chức năng để bắt đầu chấp nhận kết nối. Bây giờ mã của bạn sẽ trông như thế

PORT = 8000
ADDRESS = "0.0.0.0"
my_socket.bind((ADDRESS, PORT))
9

Nếu bạn đã mã hóa mọi thứ đúng, bây giờ bạn có thể khởi động máy chủ và kết nối một số máy khách với nó, gửi tin nhắn, v.v.

Bước 5. Một số vấn đề cần giải quyết

Nếu bạn đã kiểm tra trò chuyện, bạn sẽ nhận thấy một số vấn đề, thứ nhất, khi tin nhắn được gửi, chúng tôi không có cách nào để biết ai đã gửi tin nhắn và thứ hai, (cái này ít hiển thị hơn) nhưng chúng tôi đã tạo ra không có cách nào.

Thêm biệt danh vào ứng dụng của chúng tôi

Vì vậy, chúng tôi có hai tùy chọn để triển khai biệt hiệu, chúng tôi có thể triển khai điều này ở phía máy chủ hoặc phía máy khách. Để đơn giản ở đây chúng ta sẽ chọn tùy chọn thứ hai. (Hãy nhớ rằng phòng trò chuyện của chúng tôi hoàn toàn không được bảo mật, có nhiều cách khai thác nhưng chúng tôi không quan tâm đến điều đó. )

Tập lệnh máy khách sẽ cần yêu cầu người dùng chọn biệt hiệu, sau đó gửi biệt hiệu cùng với tin nhắn. Điều này không phức tạp lắm

my_socket.listen()
client, client_address = my_socket.accept()
0

Và chúng tôi có thể xác minh biệt hiệu không trống

my_socket.listen()
client, client_address = my_socket.accept()
1

Và bây giờ chúng ta có biệt danh của người dùng, chúng ta có thể gửi biệt hiệu đó cùng với tin nhắn, chức năng

message = client.recv(1024) #bytes
print(message.decode())
9 của chúng ta bây giờ trông như thế này

my_socket.listen()
client, client_address = my_socket.accept()
2

Và bây giờ, người dùng có một biệt danh, nó không phức tạp lắm.

import socket
10 của bạn sẽ trông như thế này

my_socket.listen()
client, client_address = my_socket.accept()
3

Bây giờ máy chủ sẽ xử lý nếu máy khách ngắt kết nối

Bạn có thể nhận thấy rằng khi máy khách ngắt kết nối (sử dụng Ctrl+C), máy chủ có một hành vi rất lạ khi nó không ngừng in

import socket
11

Vì vậy, trước tiên, hãy đảm bảo rằng khách hàng chỉ gửi tin nhắn nếu nó không trống

my_socket.listen()
client, client_address = my_socket.accept()
4

Và máy chủ chỉ in thông báo nếu nó không trống, nếu có nghĩa là máy khách đã bị ngắt kết nối, vì vậy chúng ta có thể dừng chuỗi nghe (để dừng chuỗi chúng ta chỉ cần thoát khỏi chức năng)

my_socket.listen()
client, client_address = my_socket.accept()
5

Bây giờ mã của bạn sẽ trông như thế này

my_socket.listen()
client, client_address = my_socket.accept()
6

Và kịch bản khách hàng

my_socket.listen()
client, client_address = my_socket.accept()
7

Nếu mã của bạn giống như vậy, phòng chat sẽ hoạt động. Rõ ràng là có rất nhiều thứ bạn có thể thêm vào nhưng hướng dẫn này chỉ là xây dựng một cuộc trò chuyện rất đơn giản

Trò chuyện ổ cắm là gì?

Ứng dụng trò chuyện đã hoàn thành. ổ cắm. io là thư viện JavaScript cho phép giao tiếp theo thời gian thực giữa máy khách và máy chủ . Nó được xây dựng dựa trên Websockets API.

Ổ cắm trong python là gì?

Ổ cắm và API ổ cắm được 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 logic, cục bộ 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.