Kho lưu trữ của ứng dụng này bao gồm hai tệp python, máy chủ. py và khách hàng. py. người phục vụ. py là tập lệnh chạy máy chủ mà tất cả các máy khách sẽ sử dụng để giao tiếp với nhau. Và khách hàng. py sẽ được máy khách sử dụng để kết nối với máy chủ và gửi tin nhắn cho các máy khách khác
Vì vậy, chúng tôi sẽ bắt đầu bằng máy chủ. tập lệnh py
Tạo máy chủ. py
Trước hết, chúng tôi sẽ nhập tất cả các mô-đun cần thiết của máy chủ. py
import socket
import threading
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Chúng tôi sẽ cần mô-đun ổ cắm để giao tiếp với khách hàng và mô-đun luồng để tạo chuỗi tiếp tục lắng nghe tin nhắn từ khách hàng
Tiếp theo chúng ta sẽ thiết lập một số biến
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
HOST và PORT ở đây xác định máy chủ và cổng mà máy chủ sẽ chạy, LISTENER_LIMIT lưu trữ số lượng máy khách có thể kết nối với máy chủ tại một thời điểm. Và cuối cùng, active_clients sẽ lưu trữ tất cả người dùng sẽ được kết nối với máy chủ trong bất kỳ trường hợp nào
Tiếp theo chúng ta sẽ tạo hàm listen_for_messages
def listen_for_messages[client, username]:
while 1:
message = client.recv[2048].decode['utf-8']
if message != '':
final_msg = username + '~' + message
send_messages_to_all[final_msg]
else:
print[f"The message send from client {username} is
empty"]
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Chức năng này sẽ tiếp tục lắng nghe tin nhắn từ các máy khách được kết nối. Trong trường hợp nếu nhận được tin nhắn, nó sẽ gọi hàm send_message_to_all để gửi tin nhắn đã nhận cho tất cả các máy khách hiện đang kết nối
Tiếp theo chúng ta tạo hàm send_message_to_client
def send_message_to_client[client, message]:
client.sendall[message.encode[]]
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Chức năng này được sử dụng để gửi tin nhắn đến một khách hàng
Tiếp theo chúng ta tạo hàm send_message_to_all
def send_messages_to_all[message]:
for user in active_clients:
send_message_to_client[user[1], message]
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Chức năng này sẽ gửi tin nhắn đến tất cả các máy khách được kết nối bằng cách gọi hàm send_message cho từng máy khách được kết nối
Tiếp theo chúng ta tạo hàm client_handler
def client_handler[client]:
# Server will listen for client message that will
# Contain the username
while 1:
username = client.recv[2048].decode['utf-8']
if username != '':
active_clients.append[[username, client]]
prompt_message = "SERVER~" + f"{username} added to
the chat"
send_messages_to_all[prompt_message]
break
else:
print["Client username is empty"]
threading.Thread[target=listen_for_messages, args=[client,
username, ]].start[]
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Hàm này sẽ sử dụng đối tượng máy khách [được giải thích sau trong blog này] mà chúng ta nhận được khi kết nối với máy khách, để lấy tên người dùng từ máy khách, thêm máy khách vào danh sách máy khách đang hoạt động và bắt đầu trình nghe .
Lưu ý. Chức năng này cũng được thực hiện dưới dạng một chuỗi, cho mỗi máy khách được kết nối mới.
def main[]:
server = socket.socket[socket.AF_INET, socket.SOCK_STREAM]
try:
server.bind[[HOST, PORT]]
print[f"Running the server on {HOST} {PORT}"]
except:
print[f"Unable to bind to host {HOST} and port
{PORT}"]
server.listen[LISTENER_LIMIT]
while 1:
client, address = server.accept[]
print[f"Successfully connected to client {address[0]} {address[1]}"]
threading.Thread[target=client_handler, args=[client, ]].start[]
if __name__ == '__main__':
main[]
Vào chế độ toàn màn hình Thoát chế độ toàn màn hình
Và cuối cùng chúng ta có chức năng chính, thực hiện công việc của
- Tạo một ổ cắm [đóng vai trò là máy chủ]
- Liên kết IP và Cổng với máy chủ
- Thiết lập giới hạn người nghe
- Chấp nhận mọi kết nối sắp tới từ khách hàng
- Gọi trình xử lý ứng dụng khách cho bất kỳ ứng dụng khách được kết nối mới nào
Đó là tất cả về mã phía máy chủ, Mã phía máy chủ hơi dài để giải thích trong một blog duy nhất, vì vậy tôi đã tạo danh sách phát này trên YouTube, nơi tôi giải thích tất cả mã, cả mã phía máy chủ và máy khách. Vì vậy, hãy xem danh sách phát này để hiểu mã phía máy khách
Chúng ta đã hoàn thành những kiến thức cơ bản về cách làm việc với socket và bây giờ chúng ta đã sẵn sàng thử thực sự xây dựng thứ gì đó với chúng, vì vậy, trong hướng dẫn về socket với Python này, chúng ta sẽ xây dựng một ứng dụng trò chuyện dựa trên bảng điều khiển
Để bắt đầu, chúng ta sẽ xây dựng
server_socket.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1]3. Các chức năng của máy chủ của chúng tôi sẽ là gì?
Đầu tiên, máy chủ cần chấp nhận các kết nối mới từ máy khách. Từ đây, chúng ta cần nghĩ ra một số cách để xác định người dùng duy nhất của mình. Chúng tôi có thể hiển thị người dùng theo địa chỉ IP, nhưng hầu hết mọi người có xu hướng nghĩ ra một số loại tên người dùng, vì vậy trước tiên máy chủ của chúng tôi sẽ cho phép khách hàng kết nối và chọn tên người dùng. Ngoài điều này, máy chủ sẽ thu thập các tin nhắn đến và sau đó phân phối chúng cho các máy khách được kết nối còn lại
Vì vậy, chúng tôi sẽ bắt đầu với việc nhập và một số giá trị bắt đầu
________số 8Không có gì mới ở đây ngoại trừ việc nhập khẩu
server_socket.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1]4. Đây là gì? . Nó đặc biệt hữu ích trong trường hợp chúng tôi đang cố gắng giám sát đồng thời nhiều kết nối. Mặc dù bạn có thể sử dụng vòng lặp for để lặp qua tất cả các ổ cắm, nhưng sử dụng
server_socket.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1]4 sẽ hiệu quả hơn nhiều và sẽ mở rộng quy mô tốt hơn nhiều, chủ yếu là vì nó sẽ hoạt động trên lớp hệ điều hành của bạn, thay vì toàn bộ Python. Về cách sử dụng nó, chúng ta sẽ nói về nó nhiều hơn khi đến điểm đó
Ban đầu thiết lập ổ cắm của chúng tôi
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
2Tiếp theo, chúng ta có thể thiết lập như sau để vượt qua "Địa chỉ đã được sử dụng" mà chúng ta thường gặp khi xây dựng chương trình của mình
server_socket.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1]
Điều này sửa đổi ổ cắm để cho phép chúng tôi sử dụng lại địa chỉ
Tiếp theo, chúng tôi liên kết và lắng nghe
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
4Tiếp theo, chúng tôi sẽ tạo một danh sách các ổ cắm cho
server_socket.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1]4 để theo dõi, cũng như bắt đầu lệnh
server_socket.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1]8 của chúng tôi
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
7Một số thông tin gỡ lỗi
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
8Bây giờ, công việc chính của máy chủ này là nhận tin nhắn, sau đó phân tán chúng đến các máy khách được kết nối. Để nhận tin nhắn, chúng ta sẽ tạo một chức năng
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
9Bước 1 để nhận tin nhắn là đọc tiêu đề
def listen_for_messages[client, username]:
while 1:
message = client.recv[2048].decode['utf-8']
if message != '':
final_msg = username + '~' + message
send_messages_to_all[final_msg]
else:
print[f"The message send from client {username} is
empty"]
0Nếu khách hàng đóng kết nối một cách duyên dáng, thì một
server_socket.setsockopt[socket.SOL_SOCKET, socket.SO_REUSEADDR, 1]9 sẽ được cấp và sẽ không có tiêu đề. Chúng tôi có thể xử lý điều đó với
def listen_for_messages[client, username]:
while 1:
message = client.recv[2048].decode['utf-8']
if message != '':
final_msg = username + '~' + message
send_messages_to_all[final_msg]
else:
print[f"The message send from client {username} is
empty"]
2Sau đó, chúng tôi có thể chuyển đổi tiêu đề của mình thành độ dài
def listen_for_messages[client, username]:
while 1:
message = client.recv[2048].decode['utf-8']
if message != '':
final_msg = username + '~' + message
send_messages_to_all[final_msg]
else:
print[f"The message send from client {username} is
empty"]
3Cuối cùng, chúng ta có thể trả về một số dữ liệu có ý nghĩa
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
20Mã đầy đủ ngay bây giờ
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
21Bây giờ, những gì chúng tôi muốn làm là, trong một vòng lặp liên tục, nhận tin nhắn cho tất cả các ổ cắm máy khách của chúng tôi, sau đó gửi tất cả tin nhắn đến tất cả các ổ cắm máy khách. Để bắt đầu, chúng tôi sẽ sử dụng vòng lặp
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
40 và sau đó chúng tôi sẽ sử dụng HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
41HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
22Điều này không hoàn toàn đơn giản, nhưng nó khá đơn giản. Chúng tôi hoàn toàn sử dụng
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
41 ở đây cho i/o cấp hệ điều hành đã nói ở trên cho ổ cắm của chúng tôi. Hàm này lấy tham số là HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
43, HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
44 và HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
45. lần lượt là danh sách đọc, danh sách ghi và danh sách lỗi. Trả về của hàm này là 3 phần tử giống nhau trong đó trả về là "tập hợp con" của danh sách đầu vào trong đó tập hợp con là danh sách các ổ cắm đã sẵn sàngBây giờ, từ đây, chúng ta sẽ lặp lại danh sách
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
46. Đây là những ổ cắm có dữ liệu được đọcHOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
23Nếu ổ cắm được thông báo là ổ cắm máy chủ của chúng tôi, thì điều này có nghĩa là chúng tôi vừa có một kết nối mới mà chúng tôi muốn xử lý
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
24Vì vậy, với
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
47, chúng tôi nhận được ổ cắm máy khách duy nhất đó và địa chỉ của họ. Sau đó, chúng tôi lưu trữ tên người dùng đã chọn của họ thành tên họ đã chọn [đây phải là thứ đầu tiên khách hàng sẽ gửi]. Nếu vì một lý do nào đó, điều đó không xảy ra [chẳng hạn như khách hàng đã đóng trước khi gửi tên], thì chúng tôi sẽ tiếp tụcTiếp theo, chúng tôi muốn nối thêm
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
48 mới này vào HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
49 của chúng tôiHOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
25Sau này, chúng tôi muốn lưu tên người dùng của khách hàng này, chúng tôi sẽ lưu tên người dùng này làm giá trị cho khóa là đối tượng ổ cắm
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
26Nếu ổ cắm được thông báo không phải là ổ cắm máy chủ, thì điều này có nghĩa là thay vào đó, chúng tôi có một thông báo để đọc
HOST = '127.0.0.1'
PORT = 1234
LISTENER_LIMIT = 5
active_clients = []
27Trước khi chúng tôi cố gắng đọc tin nhắn, hãy đảm bảo rằng một tin nhắn tồn tại. Nếu khách hàng ngắt kết nối, thì thông báo sẽ trống