Ứng dụng trò chuyện GUI trong Python

Gần đây tôi đã đi sâu vào thế giới tuyệt vời của mạng máy tính. Một trong những dự án thú vị mà tôi đã tạo là một ứng dụng phòng trò chuyện đơn giản hỗ trợ nhắn tin theo thời gian thực giữa các khách hàng khác nhau

zeyu2001 / pychat

Ứng dụng phòng trò chuyện Python thời gian thực với Tkinter GUI

Tại bất kỳ thời điểm nào trong hướng dẫn này, bạn có thể tham khảo mã nguồn của tôi trong GitHub. Mục đích của hướng dẫn này là giới thiệu một số lý thuyết mạng cơ bản đồng thời cung cấp kinh nghiệm lập trình socket thực tế. Nếu tại bất kỳ thời điểm nào, bạn thấy rằng mình đã cảm thấy thoải mái với lý thuyết liên quan, vui lòng bỏ qua phần tiếp theo

điều kiện tiên quyết

Bạn nên biết Python cơ bản. Ngoài ra, không có gì khác. Trong quá trình tạo ứng dụng này, bạn cũng sẽ tìm hiểu về mạng máy tính cơ bản và kiến ​​trúc máy khách-máy chủ

Chúng tôi sẽ sử dụng Tkinter và ổ cắm, cả hai đều có sẵn trong thư viện chuẩn của Python. Không có gì bạn cần phải cài đặt

Kiến trúc máy khách-máy chủ

Ảnh của İsmail Enes Ayhan trên Bapt

Kiến trúc máy khách-máy chủ là một mô hình điện toán cơ bản trong đó máy khách yêu cầu dịch vụ từ máy chủ, trong khi máy chủ xử lý các yêu cầu này và cung cấp dịch vụ cho máy khách

Trên thực tế, trình duyệt web của bạn là ứng dụng khách yêu cầu dịch vụ web từ máy chủ web của Medium thông qua Giao thức truyền siêu văn bản [HTTP] ngay bây giờ. Máy chủ web của Medium xử lý yêu cầu của bạn và trả về các tài liệu HTML, biểu định kiểu CSS, tệp JavaScript và hình ảnh để trình duyệt web của bạn có thể hiển thị trang web theo cách của nó

Kiến trúc máy khách-máy chủ

Hơn nữa, một máy chủ có thể phục vụ nhiều máy khách. Trong ứng dụng của chúng tôi, chúng tôi muốn nhiều khách hàng nói chuyện trong thời gian thực. Phần mềm máy khách sẽ gửi tin nhắn đến máy chủ phòng trò chuyện và máy chủ phòng trò chuyện sẽ phát tin nhắn của chúng tôi tới tất cả các máy khách được kết nối khác

Nghị định thư, Nghị định thư, Nghị định thư

Giao tiếp qua mạng sử dụng cái mà chúng tôi gọi là ngăn xếp giao thức — xây dựng các cuộc hội thoại cấp cao hơn, phức tạp hơn trên các cuộc hội thoại đơn giản hơn, thô sơ hơn. Các lớp mạng có thể được biểu diễn bằng mô hình OSI và mô hình TCP/IP. Mỗi lớp mạng tương ứng với một nhóm các giao thức mạng dành riêng cho từng lớp

Ngăn xếp giao thức mạng

Với mục đích của ứng dụng này, chúng ta không cần quan tâm đến nhiều giao thức cấp thấp hơn. Nhưng chúng tôi cần biết rằng chúng tôi đang sử dụng một thứ gọi là Giao thức điều khiển truyền tải [TCP]

TCP và UDP là các giao thức tầng vận chuyển — chúng chi phối cách dữ liệu được gửi từ điểm này sang điểm khác. Chúng tôi đang xây dựng dựa trên TCP, điều đó có nghĩa là chúng tôi không cần quan tâm đến việc dữ liệu được gửi như thế nào, chỉ cần dữ liệu được gửi là gì và ở đâu

Sự khác biệt chính giữa TCP và UDP là TCP đảm bảo phân phối đáng tin cậy, không có bất kỳ thông tin nào bị mất, trùng lặp hoặc không theo thứ tự. UDP không đảm bảo điều tương tự và để nó cho lớp ứng dụng xử lý các gói bị rơi. Nó yêu cầu máy chủ xác nhận đã nhận dữ liệu

TCP so với UDP

UDP thường được sử dụng cho các lần truyền nhạy cảm với thời gian trong đó một gói bị mất được ưu tiên hơn là chờ các gói bị mất được truyền lại. Ví dụ, hãy tưởng tượng một cuộc gọi thoại trong thời gian thực. Nếu một gói đã bị mất, sẽ không có ý nghĩa gì nếu đợi đoạn âm thanh đó đến bởi vì vào thời điểm đó, nó đã quá cũ. Hơn nữa, bạn vẫn có thể ghép nối cuộc trò chuyện với nhau mà không cần gói âm thanh đó.

Mặt khác, TCP sẽ tiếp tục ngoan cố gửi lại đoạn âm thanh bị mất đó mặc dù nó đã quá cũ để sử dụng. Tuy nhiên, đối với hầu hết các ứng dụng khác, khía cạnh này của TCP cực kỳ có giá trị. Trong ứng dụng trò chuyện của chúng tôi, chúng tôi không muốn phải xử lý các gói bị mất vì chúng tôi luôn muốn nhận được các tin nhắn hoàn chỉnh mà không có bất kỳ lỗi nào

Máy chủ phòng chat

Hãy bắt đầu với tập lệnh máy chủ của chúng tôi. Chúng tôi bắt đầu bằng cách xác định một lớp

Source [IP: Port Number] → Destination [IP: Port Number]
1 trong
Source [IP: Port Number] → Destination [IP: Port Number]
2

#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Khái niệm cơ bản về luồng

Lưu ý rằng chúng tôi đang sử dụng đa luồng để cho phép nhiều đoạn mã chạy đồng thời. Lớp

Source [IP: Port Number] → Destination [IP: Port Number]
1 của chúng ta kế thừa từ lớp
Source [IP: Port Number] → Destination [IP: Port Number]
4 của Python, do đó tạo ra một luồng. Chúng ta cần xác định logic cho luồng
Source [IP: Port Number] → Destination [IP: Port Number]
1 của mình trong phương thức
Source [IP: Port Number] → Destination [IP: Port Number]
6. Khi
Source [IP: Port Number] → Destination [IP: Port Number]
7 được gọi trên đối tượng
Source [IP: Port Number] → Destination [IP: Port Number]
1, thì
Source [IP: Port Number] → Destination [IP: Port Number]
6 sẽ được thực thi song song với luồng chính

Khái niệm cơ bản về ổ cắm

Ổ cắm là địa chỉ IP + cặp số cổng. Một địa chỉ IP xác định một máy chủ lưu trữ. Tuy nhiên, một máy chủ có thể có nhiều ứng dụng khác nhau chạy cùng một lúc. Làm cách nào để hệ điều hành [HĐH] của bạn biết rằng phản hồi HTTP dành cho trình duyệt web của bạn chứ không phải Call of Duty. Chiến tranh hiện đại? . cuộc gọi của nhiệm vụ. Modern Warfare sử dụng phạm vi cổng TCP 27014–27050 chẳng hạn

Do đó, bất kỳ giao tiếp nào giữa hai thiết bị mạng đều cần một cặp ổ cắm

Source [IP: Port Number] → Destination [IP: Port Number]

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Tạo một ổ cắm

Hãy bắt đầu xác định logic luồng của chúng tôi. Thêm phần sau vào phương thức

Source [IP: Port Number] → Destination [IP: Port Number]
6

Source [IP: Port Number] → Destination [IP: Port Number]
2

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Đầu tiên, chúng tôi đã tạo một đối tượng

Source [IP: Port Number] → Destination [IP: Port Number]
21.
Source [IP: Port Number] → Destination [IP: Port Number]
22 có hai đối số. họ địa chỉ và loại ổ cắm. Họ địa chỉ
Source [IP: Port Number] → Destination [IP: Port Number]
23 được sử dụng cho mạng IP. Loại ổ cắm
Source [IP: Port Number] → Destination [IP: Port Number]
24 được sử dụng cho các luồng dữ liệu được điều khiển theo luồng đáng tin cậy, chẳng hạn như các luồng do TCP cung cấp. Mặt khác, UDP yêu cầu loại ổ cắm dựa trên gói,
Source [IP: Port Number] → Destination [IP: Port Number]
25

Tiếp theo, chúng tôi đặt tùy chọn

Source [IP: Port Number] → Destination [IP: Port Number]
26. Bạn có thể đọc thêm về các tùy chọn socket trong trang hướng dẫn sử dụng Linux socket[7]. Tùy chọn này cho phép máy chủ sử dụng cùng một cổng sau khi kết nối cũ bị đóng [thông thường, bạn sẽ phải đợi trong vài phút]

Sau đó, chúng tôi sử dụng

Source [IP: Port Number] → Destination [IP: Port Number]
27 để liên kết đối tượng
Source [IP: Port Number] → Destination [IP: Port Number]
22 với một địa chỉ ổ cắm trên máy chủ.
Source [IP: Port Number] → Destination [IP: Port Number]
27 nhận vào một bộ, ở định dạng

#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
2

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Lưu ý rằng một máy có thể có nhiều giao diện IP bên ngoài. bạn có thể tìm thấy của mình bằng cách sử dụng lệnh

#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
20 tại thiết bị đầu cuối [hoặc
#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
21 cho Windows]

Chạy lệnh ifconfig từ thiết bị đầu cuối

Bạn nên biết rằng kết quả đầu tiên tôi nhận được, giao diện

#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
22, là một kết quả rất đặc biệt. Đây là giao diện loopback, chỉ các chương trình khác chạy trên cùng một máy mới có thể truy cập được. Nó có địa chỉ IP là 127. 0. 0. 1 và chỉ có ý nghĩa cục bộ trong máy của bạn. Nó có tên máy chủ là 'localhost' và cung cấp một môi trường thử nghiệm an toàn

Trong lệnh

Source [IP: Port Number] → Destination [IP: Port Number]
27, chúng tôi có thể chỉ định bất kỳ giao diện IP nào [ngay cả giao diện loopback. ] hoặc chúng ta có thể sử dụng một chuỗi rỗng
#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
24 làm ký tự đại diện để cho biết rằng chúng ta sẵn sàng nhận các gói đến máy chủ thông qua bất kỳ giao diện mạng nào của nó. Trong chương trình của chúng tôi, chúng tôi sẽ để điều này cho người dùng, như bạn sẽ thấy sau

Cuối cùng, chúng tôi sử dụng

#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
25 để chỉ ra rằng đây là ổ cắm nghe. TCP sử dụng hai loại ổ cắm. ổ cắm nghe và ổ cắm được kết nối. Sau khi gọi
#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
25 trên ổ cắm, ổ cắm này sẽ trở thành ổ cắm lắng nghe và chỉ có thể tạo điều kiện thiết lập kết nối TCP thông qua bắt tay chứ không phải chuyển dữ liệu thực sự. Chúng tôi sẽ cần tạo một ổ cắm hoàn toàn mới bất cứ khi nào máy khách kết nối, để gửi và nhận dữ liệu. Tiếp tục đi

Chấp nhận kết nối

Source [IP: Port Number] → Destination [IP: Port Number]
0

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Chúng tôi tạo một vòng lặp vô hạn để lắng nghe các kết nối khách hàng mới. Cuộc gọi

#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
27 sẽ đợi một máy khách mới kết nối và khi thực hiện xong, trả về một ổ cắm được kết nối mới cùng với địa chỉ ổ cắm của máy khách được kết nối

Một vài phương pháp khác để giới thiệu.

#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
28 trả về địa chỉ ổ cắm ở đầu kia của kết nối [trong trường hợp này là máy khách] trong khi
#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
29 trả về địa chỉ ổ cắm mà đối tượng ổ cắm được liên kết

Chúng tôi cần một cách để giao tiếp với từng khách hàng riêng lẻ, nhưng đồng thời, chúng tôi cần lắng nghe các kết nối mới từ các khách hàng tiềm năng khác. Cách chúng tôi thực hiện việc này là tạo một luồng

Source [IP: Port Number] → Destination [IP: Port Number]
00 mới [chúng tôi sẽ xác định điều này sau] mỗi khi một máy khách mới kết nối và luồng này chạy song song với luồng
Source [IP: Port Number] → Destination [IP: Port Number]
1. Máy chủ cũng cần một cách để quản lý tất cả các kết nối máy khách đang hoạt động, do đó, nó lưu trữ các kết nối đang hoạt động dưới dạng đối tượng
Source [IP: Port Number] → Destination [IP: Port Number]
00 trong
Source [IP: Port Number] → Destination [IP: Port Number]
03

'Phát thanh truyền hình'

Ứng dụng phòng trò chuyện nhỏ của chúng tôi sẽ hoạt động như thế nào

  1. Máy khách gửi tin nhắn đến máy chủ từ dòng lệnh hoặc GUI

  2. Máy chủ nhận và xử lý tin nhắn

  3. Máy chủ gửi tin nhắn đến tất cả các máy khách được kết nối khác

  4. Máy khách sẽ hiển thị thông báo trong dòng lệnh hoặc GUI

Hãy thêm chức năng 'broadcasting' từ bước 3 vào lớp

Source [IP: Port Number] → Destination [IP: Port Number]
1. Tôi thận trọng khi sử dụng từ 'phát sóng' vì phát sóng đề cập đến một khái niệm hoàn toàn khác trong ngữ cảnh mạng máy tính. Chúng tôi thực sự đang gửi nhiều unicast, là truyền một-một đến từng khách hàng được kết nối riêng lẻ

Source [IP: Port Number] → Destination [IP: Port Number]
9

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Lưu ý rằng

Source [IP: Port Number] → Destination [IP: Port Number]
03 là danh sách các đối tượng
Source [IP: Port Number] → Destination [IP: Port Number]
00 đại diện cho các kết nối máy khách đang hoạt động. Chúng ta sẽ định nghĩa lớp
Source [IP: Port Number] → Destination [IP: Port Number]
00 bên dưới

gửi và nhận

Lớp

Source [IP: Port Number] → Destination [IP: Port Number]
00 sẽ tạo điều kiện giao tiếp với các khách hàng cá nhân

Source [IP: Port Number] → Destination [IP: Port Number]
4

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Một lần nữa, chúng tôi tạo ra một vòng lặp vô hạn. Lần này, thay vì lắng nghe các kết nối mới, chúng tôi đang lắng nghe dữ liệu do khách hàng gửi

Khi

Source [IP: Port Number] → Destination [IP: Port Number]
09 được gọi, nó sẽ đợi dữ liệu đến. Nếu không có dữ liệu,
Source [IP: Port Number] → Destination [IP: Port Number]
09 sẽ không trả về [nó bị 'chặn'] và chương trình tạm dừng cho đến khi có dữ liệu. Các cuộc gọi như
#!/usr/bin/env python3

import threading
import socket
import argparse
import os

class Server[threading.Thread]:

    def __init__[self, host, port]:
        super[].__init__[]
        self.connections = []
        self.host = host
        self.port = port

    def run[self]:
        pass
27 và
Source [IP: Port Number] → Destination [IP: Port Number]
09 khiến chương trình đợi cho đến khi một số dữ liệu mới đến, cho phép nó quay trở lại, được gọi là cuộc gọi chặn. Dữ liệu được gửi và nhận qua mạng dưới dạng chuỗi phụ, do đó cần được mã hóa và giải mã bằng cách sử dụng
Source [IP: Port Number] → Destination [IP: Port Number]
93 và
Source [IP: Port Number] → Destination [IP: Port Number]
94 tương ứng

Source [IP: Port Number] → Destination [IP: Port Number]
09 nhận một đối số,
Source [IP: Port Number] → Destination [IP: Port Number]
96, chỉ định lượng dữ liệu tối đa được nhận cùng một lúc

Mặt khác,

Source [IP: Port Number] → Destination [IP: Port Number]
97 gửi dữ liệu từ ổ cắm đến thiết bị ngang hàng được kết nối của nó

Một vấn đề với cả

Source [IP: Port Number] → Destination [IP: Port Number]
97 và
Source [IP: Port Number] → Destination [IP: Port Number]
09 là có một khả năng nhỏ là chỉ một phần dữ liệu được gửi hoặc nhận, bởi vì bộ đệm gửi đi hoặc đến đã gần đầy, vì vậy nó xếp bất kỳ dữ liệu nào có thể vào hàng đợi, trong khi để lại phần dữ liệu còn lại . Điều này trở thành vấn đề khi
Source [IP: Port Number] → Destination [IP: Port Number]
97 trả về, nhưng trên thực tế, một số dữ liệu vẫn chưa được gửi. Chúng tôi có thể đặt
Source [IP: Port Number] → Destination [IP: Port Number]
97 trong một vòng lặp hoặc chúng tôi có thể sử dụng
Source [IP: Port Number] → Destination [IP: Port Number]
42 như một cách đơn giản để nói “Tôi muốn gửi tất cả dữ liệu”

ổ cắm đã đóng

Một điều bạn sẽ nhận thấy trong đoạn mã trên là chúng tôi có thể biết liệu máy khách đã đóng kết thúc kết nối hay chưa. Khi ổ cắm máy khách được đóng lại, ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____

Vì vậy, khi chúng tôi thấy rằng

Source [IP: Port Number] → Destination [IP: Port Number]
09 trả về một chuỗi rỗng [trong câu lệnh khác], chúng tôi cũng
Source [IP: Port Number] → Destination [IP: Port Number]
47 phía kết nối của chúng tôi, loại bỏ luồng
Source [IP: Port Number] → Destination [IP: Port Number]
00 khỏi danh sách các kết nối đang hoạt động và kết thúc luồng

Lần chỉnh sửa cuối cùng

Source [IP: Port Number] → Destination [IP: Port Number]
5

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Chúng tôi cho phép người dùng chỉ định địa chỉ máy chủ và số cổng tại dòng lệnh và nhập 'q' tại bất kỳ điểm nào từ dòng lệnh để kết thúc chương trình

Bây giờ bạn có thể chạy tập lệnh máy chủ của mình

Máy chủ đang chạy. py từ thiết bị đầu cuối

khách hàng phòng chat

Máy chủ không thực sự làm được gì nhiều nếu không có máy khách kết nối với nó. Hãy tạo một tệp

Source [IP: Port Number] → Destination [IP: Port Number]
49

Source [IP: Port Number] → Destination [IP: Port Number]
7

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Trong khi tạo tập lệnh máy chủ, tôi hy vọng tôi đã giải thích rõ ràng phần lớn lý thuyết cho bạn. Các quy tắc tương tự được áp dụng ở đây, ngoại trừ chúng tôi có một chuỗi Gửi luôn lắng nghe đầu vào của người dùng từ dòng lệnh. Chúng tôi sẽ thêm GUI sau, nhưng nó tuân theo nhiều logic giống nhau. Mọi dữ liệu nhận được sẽ được hiển thị trên giao diện máy khách và mọi dữ liệu được gửi sẽ được máy chủ xử lý để truyền đến các máy khách được kết nối khác

Một lần nữa, chúng tôi sử dụng đa luồng. Lần này, nó là để cho các hoạt động gửi và nhận chạy song song với nhau. Bằng cách này, phòng trò chuyện của chúng tôi hoạt động theo thời gian thực [thay vì xen kẽ giữa các cuộc gọi

Source [IP: Port Number] → Destination [IP: Port Number]
97 và
Source [IP: Port Number] → Destination [IP: Port Number]
09]

Kết nối với máy chủ

Source [IP: Port Number] → Destination [IP: Port Number]
0

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Máy khách gọi phương thức

Source [IP: Port Number] → Destination [IP: Port Number]
52 để kết nối với một địa chỉ ổ cắm được chỉ định [một lần nữa, ở dạng Tuple] của máy chủ. Nếu ổ cắm được chỉ định chưa sẵn sàng nhận kết nối [e. g. bạn chưa chạy tập lệnh máy chủ], cuộc gọi
Source [IP: Port Number] → Destination [IP: Port Number]
52 sẽ không thành công

connect[] không thành công với ConnectionRefusedError

Lần chỉnh sửa cuối cùng

Source [IP: Port Number] → Destination [IP: Port Number]
0

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Kiểm tra ứng dụng dòng lệnh của chúng tôi

Những gì chúng tôi đã làm là xây dựng một phòng chat dòng lệnh hoạt động đầy đủ

Bạn có thể chạy tập lệnh máy chủ của mình bằng cách cung cấp cho nó bất kỳ giao diện IP nào của máy [bạn cũng có thể sử dụng tên máy chủ của mình. ]. Nếu bạn thích, bạn có thể chỉ cần sử dụng '127. 0. 0. 1’ hoặc ‘localhost’ nếu bạn chỉ thử nghiệm điều này trên một máy

Máy chủ đang chạy. py với một địa chỉ IP

Máy chủ đang chạy. py với tên máy chủ

Các quy tắc tương tự áp dụng cho tập lệnh máy khách. Mở một cửa sổ đầu cuối riêng biệt và chạy

Source [IP: Port Number] → Destination [IP: Port Number]
49

Máy khách đang chạy. py với địa chỉ IP của máy chủ

Máy khách đang chạy. py với tên máy chủ

Mở ba cửa sổ đầu cuối trở lên và bạn có thể có nhiều ứng dụng khách. Ngoài ra, lấy một máy khác được kết nối với cùng mạng LAN và chạy

Source [IP: Port Number] → Destination [IP: Port Number]
49 từ đó. Nếu nó nằm trong một mạng LAN khác, tường lửa của bạn có thể chặn nó

Chạy nhiều ứng dụng khách trong iTerm

Trong ảnh chụp màn hình ở trên, tôi đang chạy ba cửa sổ đầu cuối, với hai máy khách được kết nối với cùng một máy chủ

Tạo GUI

Chúng tôi vẫn chưa hoàn thành. Một ứng dụng dòng lệnh là tốt và tất cả, nhưng tạo một GUI thì sao?

Chúng tôi chỉ cần thực hiện một số điều chỉnh đối với

Source [IP: Port Number] → Destination [IP: Port Number]
49 của mình và thêm một số mã khác để tạo GUI. Bạn có thể tìm hiểu thêm về Tkinter bằng cách đọc tài liệu của nó, nhưng điều đó nằm ngoài phạm vi của hướng dẫn này

Source [IP: Port Number] → Destination [IP: Port Number]
49 hoàn chỉnh có sẵn bên dưới

và để tham khảo, mã

Source [IP: Port Number] → Destination [IP: Port Number]
2 hoàn chỉnh

Sản phẩm cuối cùng

Chạy

Source [IP: Port Number] → Destination [IP: Port Number]
2 và
Source [IP: Port Number] → Destination [IP: Port Number]
49 giống như bạn đã làm trước đây. Sau khi nhập tên của bạn, GUI sẽ bật lên

Tôi đã thiết kế cái này để bạn có thể sử dụng dòng lệnh hoặc GUI để tương tác với ứng dụng để gỡ lỗi dễ dàng hơn và xem những gì đang diễn ra đằng sau hậu trường

Sự kết luận

Đó là tất cả. Tôi hy vọng rằng bạn thích đọc nó nhiều như tôi đã thích viết nó. Thế giới mạng máy tính thực sự khá thú vị và đây chỉ là phần nổi của tảng băng chìm

Ứng dụng GUI trong Python là gì?

Giao diện người dùng đồ họa là ứng dụng có các nút, cửa sổ và nhiều tiện ích con khác mà người dùng có thể sử dụng để tương tác với ứng dụng của bạn. A good example would be a web browser. It has buttons, tabs, and a main window where all the content loads.

Chúng ta có thể tạo ứng dụng trò chuyện bằng Python không?

Vì vậy, để tạo Ứng dụng trò chuyện Python, người ta phải viết chương trình máy chủ và [các] chương trình máy khách [người gửi và người nhận] .

Bạn có thể tạo một GUI đẹp bằng Python không?

Việc tạo giao diện người dùng đồ họa [GUI] đơn giản hoạt động trên nhiều nền tảng có thể phức tạp. Nhưng không nhất thiết phải như vậy. Bạn có thể sử dụng Python và gói PySimpleGUI để tạo giao diện người dùng đẹp mắt mà bạn và người dùng của bạn sẽ thích.

GUI trong Python có dễ không?

Mặc dù cực kỳ hữu ích cho các lĩnh vực khoa học dữ liệu và máy học, Python cũng rất tuyệt vời để phát triển giao diện người dùng đồ họa. Trên thực tế, nó có nhiều khung mà ngay cả những người mới bắt đầu cũng có thể sử dụng để dễ dàng bắt đầu phát triển GUI .

Chủ Đề