Hướng dẫn python open multiple sockets - python mở nhiều ổ cắm
Ổ cắm và API ổ cắm được sử dụng để gửi tin nhắn trên 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ột mạng cục bộ, logic vào máy tính hoặc một mạng được kết nối về mặt vật lý với mạng bên ngoài, với các kết nối riêng với các mạng khác. Ví dụ rõ ràng là Internet, mà bạn kết nối thông qua ISP của bạn. Show
Trong hướng dẫn này, bạn sẽ tạo ra:
Đến cuối hướng dẫn này, bạn sẽ hiểu cách sử dụng các chức năng và phương thức chính trong mô-đun ổ cắm Python, để viết các ứng dụng máy khách của riêng bạn. Bạn sẽ biết cách sử dụng một lớp tùy chỉnh để gửi tin nhắn và dữ liệu giữa các điểm cuối mà bạn có thể xây dựng và sử dụng cho các ứng dụng của riêng bạn. Các ví dụ trong hướng dẫn này yêu cầu Python 3.6 trở lên, và đã được thử nghiệm bằng Python 3.10. Để tận dụng tối đa hướng dẫn này, tốt nhất là bạn nên tải xuống mã nguồn và có nó để tham khảo trong khi đọc: Mạng và ổ cắm là những chủ đề lớn. Tập theo nghĩa đen đã được viết về chúng. Nếu bạn mới sử dụng ổ cắm hoặc kết nối mạng, thì điều đó hoàn toàn bình thường nếu bạn cảm thấy choáng ngợp với tất cả các thuật ngữ và mảnh. Mặc dù vậy, don không được khuyến khích. Hướng dẫn này là dành cho bạn! Như với bất cứ điều gì liên quan đến Python, bạn có thể học một chút tại một thời điểm. Đánh dấu bài viết này và quay lại khi bạn đã sẵn sàng cho phần tiếp theo. Tiểu sửỔ cắm có một lịch sử lâu dài. Việc sử dụng chúng bắt nguồn từ ARPANET vào năm 1971 và sau đó trở thành API trong Hệ điều hành Phân phối Phần mềm Berkeley (BSD) được phát hành năm 1983 có tên Berkeley Sockets. Khi Internet cất cánh vào những năm 1990 với World Wide Web, lập trình mạng cũng vậy. Máy chủ web và trình duyệt weren là các ứng dụng duy nhất tận dụng các mạng mới được kết nối và sử dụng ổ cắm. Các ứng dụng máy khách-máy chủ của tất cả các loại và kích thước được sử dụng rộng rãi. Ngày nay, mặc dù các giao thức cơ bản được sử dụng bởi API ổ cắm đã phát triển qua nhiều năm và các giao thức mới đã phát triển, API cấp thấp vẫn giữ nguyên. Loại ứng dụng ổ cắm phổ biến nhất là các ứng dụng máy khách-máy khách, trong đó một bên hoạt động như máy chủ và chờ kết nối từ máy khách. Đây là loại ứng dụng mà bạn sẽ tạo trong hướng dẫn này. Cụ thể hơn, bạn sẽ tập trung vào API ổ cắm cho ổ cắm Internet, đôi khi được gọi là ổ cắm Berkeley hoặc BSD. Ngoài ra còn có các ổ cắm miền UNIX, chỉ có thể được sử dụng để giao tiếp giữa các quy trình trên cùng một máy chủ. Tổng quan API ổ cắmMô -đun ổ cắm Python cung cấp giao diện cho API Berkeley Sockets. Đây là mô -đun mà bạn sẽ sử dụng trong hướng dẫn này. Các hàm và phương thức API ổ cắm chính trong mô -đun này là:
Python cung cấp một API thuận tiện và nhất quán ánh xạ trực tiếp vào các cuộc gọi hệ thống, các đối tác C. Trong phần tiếp theo, bạn sẽ học cách chúng được sử dụng cùng nhau. Là một phần của thư viện tiêu chuẩn, Python cũng có các lớp giúp sử dụng các chức năng ổ cắm cấp thấp này dễ dàng hơn. Mặc dù nó không được đề cập trong hướng dẫn này, bạn có thể kiểm tra mô -đun Socketserver, một khung cho các máy chủ mạng. Ngoài ra còn có nhiều mô-đun có sẵn thực hiện các giao thức Internet cấp cao hơn như HTTP và SMTP. Để biết tổng quan, hãy xem các giao thức Internet và hỗ trợ. Ổ cắm TCPBạn sẽ tạo một đối tượng ổ cắm bằng cách sử dụng 6, chỉ định loại ổ cắm là 7. Khi bạn làm điều đó, giao thức mặc định mà sử dụng là Giao thức điều khiển truyền (TCP). Đây là một mặc định tốt và có lẽ những gì bạn muốn.Tại sao bạn nên sử dụng TCP? Giao thức điều khiển truyền (TCP):
Ngược lại, ổ cắm giao thức datagram của người dùng (UDP) được tạo bằng 8 aren đáng tin cậy và dữ liệu được đọc bởi người nhận có thể nằm ngoài thứ tự từ người gửi.Tại sao nó quan trọng? Mạng là một hệ thống phân phối hiệu quả tốt nhất. Không có gì đảm bảo rằng dữ liệu của bạn sẽ đến đích hoặc bạn sẽ nhận được những gì đã được gửi cho bạn. Các thiết bị mạng, chẳng hạn như bộ định tuyến và công tắc, có sẵn băng thông hữu hạn và đi kèm với các giới hạn hệ thống vốn có của riêng họ. Họ có CPU, bộ nhớ, xe buýt và bộ đệm gói giao diện, giống như máy khách và máy chủ của bạn. TCP giúp bạn không phải lo lắng về việc mất gói, việc đến ngoài thứ tự và những cạm bẫy khác luôn xảy ra khi bạn giao tiếp qua một mạng. Để hiểu rõ hơn về điều này, hãy xem chuỗi các cuộc gọi API ổ cắm và luồng dữ liệu cho TCP: Lưu lượng ổ cắm TCP (Nguồn hình ảnh)Cột bên trái đại diện cho máy chủ. Ở phía bên tay phải là khách hàng. Bắt đầu từ cột trên cùng bên trái, lưu ý các cuộc gọi API mà máy chủ thực hiện để thiết lập một ổ cắm nghe nghe của người dùng:
Một ổ cắm nghe làm những gì tên của nó gợi ý. Nó lắng nghe các kết nối từ khách hàng. Khi máy khách kết nối, máy chủ gọi 0 để chấp nhận hoặc hoàn thành kết nối.Máy khách gọi 1 để thiết lập kết nối với máy chủ và bắt đầu bắt tay ba chiều. Bước bắt tay rất quan trọng vì nó đảm bảo rằng mỗi bên của kết nối có thể truy cập được trong mạng, nói cách khác là máy khách có thể tiếp cận máy chủ và ngược lại. Nó có thể chỉ là một máy chủ, máy khách hoặc máy chủ có thể tiếp cận bên kia.Ở giữa là phần Trip Trip, trong đó dữ liệu được trao đổi giữa máy khách và máy chủ bằng cách sử dụng các cuộc gọi đến 3 và 4.Ở phía dưới, máy khách và máy chủ đóng ổ cắm tương ứng của họ. Echo khách hàng và máy chủBây giờ, bạn đã nhận được một cái nhìn tổng quan về API ổ cắm và cách khách hàng và máy chủ giao tiếp, bạn đã sẵn sàng để tạo máy khách và máy chủ đầu tiên của mình. Bạn sẽ bắt đầu với một triển khai đơn giản. Máy chủ chỉ đơn giản là lặp lại bất cứ điều gì nó nhận được trở lại với máy khách. Máy chủ EchoĐây là máy chủ:
Được rồi, vậy chính xác những gì đang xảy ra trong cuộc gọi API? 6 Tạo một đối tượng ổ cắm hỗ trợ loại Trình quản lý ngữ cảnh, do đó bạn có thể sử dụng nó trong câu lệnh 8. Không cần phải gọi 9:
Các đối số được chuyển cho 7 là các hằng số được sử dụng để chỉ định loại họ địa chỉ và loại ổ cắm. 1 là gia đình địa chỉ internet cho IPv4. 2 là loại ổ cắm cho TCP, giao thức sẽ được sử dụng để vận chuyển tin nhắn trong mạng.Phương thức 8 được sử dụng để liên kết ổ cắm với giao diện mạng và số cổng cụ thể:
Các giá trị được truyền đến 8 phụ thuộc vào họ địa chỉ của ổ cắm. Trong ví dụ này, bạn đã sử dụng 5 (IPv4). Vì vậy, nó mong đợi một bộ hai: 6. 7 có thể là tên máy chủ, địa chỉ IP hoặc chuỗi trống. Nếu một địa chỉ IP được sử dụng, 7 phải là chuỗi địa chỉ có định dạng IPv4. Địa chỉ IP 9 là địa chỉ IPv4 tiêu chuẩn cho giao diện Loopback, do đó, chỉ các xử lý trên máy chủ mới có thể kết nối với máy chủ. Nếu bạn vượt qua một chuỗi trống, máy chủ sẽ chấp nhận kết nối trên tất cả các giao diện IPv4 có sẵn. 00 đại diện cho số cổng TCP để chấp nhận kết nối từ máy khách. Nó phải là một số nguyên từ 01 đến 02, vì 03 được bảo lưu. Một số hệ thống có thể yêu cầu các đặc quyền siêu nhân nếu số cổng nhỏ hơn 04.Tại đây, một lưu ý về việc sử dụng tên máy chủ với 8:
Bạn sẽ tìm hiểu thêm về điều này sau, trong việc sử dụng tên máy chủ. Hiện tại, chỉ cần hiểu rằng khi sử dụng tên máy chủ, bạn có thể thấy các kết quả khác nhau tùy thuộc vào những gì mà Lùi trả về từ quá trình giải quyết tên. Những kết quả này có thể là bất cứ điều gì. Lần đầu tiên bạn chạy ứng dụng của mình, bạn có thể nhận được địa chỉ 06. Lần tới, bạn nhận được một địa chỉ khác, 07. Lần thứ ba, bạn có thể nhận được 08, v.v.Trong ví dụ máy chủ, 9 cho phép máy chủ chấp nhận kết nối. Nó làm cho máy chủ trở thành một ổ cắm của người khác:
Phương pháp 9 có tham số 11. Nó chỉ định số lượng các kết nối không được chấp nhận mà hệ thống sẽ cho phép trước khi từ chối các kết nối mới. Bắt đầu từ Python 3.5, nó tùy chọn. Nếu không được chỉ định, giá trị 11 mặc định được chọn.Nếu máy chủ của bạn nhận được đồng thời nhiều yêu cầu kết nối, việc tăng giá trị 11 có thể giúp bằng cách đặt độ dài tối đa của hàng đợi cho các kết nối đang chờ xử lý. Giá trị tối đa phụ thuộc vào hệ thống. Ví dụ: trên Linux, xem 14.Phương thức 0 chặn thực thi và chờ kết nối đến. Khi một máy khách kết nối, nó sẽ trả về một đối tượng ổ cắm mới đại diện cho kết nối và một tuple giữ địa chỉ của máy khách. Bộ tuple sẽ chứa 6 cho các kết nối IPv4 hoặc 17 cho IPv6. Xem các gia đình địa chỉ ổ cắm trong phần tham chiếu để biết chi tiết về các giá trị tuple.Một điều mà bắt buộc phải hiểu là bây giờ bạn có một đối tượng ổ cắm mới từ 0. Điều này rất quan trọng bởi vì nó có một ổ cắm mà bạn sẽ sử dụng để giao tiếp với khách hàng. Nó khác biệt với ổ cắm nghe mà máy chủ đang sử dụng để chấp nhận các kết nối mới:
Sau khi 0 cung cấp đối tượng ổ cắm máy khách 20, vòng lặp 21 vô hạn được sử dụng để lặp qua các cuộc gọi chặn đến 22. Điều này đọc bất kỳ dữ liệu nào mà khách hàng gửi và lặp lại nó bằng cách sử dụng 23.Nếu 22 trả về một đối tượng 25 trống, 26, báo hiệu rằng máy khách đã đóng kết nối và vòng lặp bị chấm dứt. Câu lệnh 8 được sử dụng với 20 để tự động đóng ổ cắm ở cuối khối.Echo khách hàngBây giờ hãy để Lừa nhìn vào khách hàng:
So với máy chủ, máy khách khá đơn giản. Nó tạo ra một đối tượng ổ cắm, sử dụng 1 để kết nối với máy chủ và gọi 30 để gửi tin nhắn của nó. Cuối cùng, nó gọi 31 để đọc trả lời máy chủ và sau đó in nó.Chạy máy khách và máy chủ EchoTrong phần này, bạn sẽ chạy máy khách và máy chủ để xem cách họ cư xử và kiểm tra những gì xảy ra. Mở dấu nhắc thiết bị đầu cuối hoặc lệnh, điều hướng đến thư mục chứa các tập lệnh của bạn, đảm bảo rằng bạn đã cài đặt Python 3.6 trở lên và trên đường dẫn của bạn, sau đó chạy máy chủ: Thiết bị đầu cuối của bạn sẽ xuất hiện để treo. Điều đó bởi vì máy chủ bị chặn, hoặc bị treo, trên 0:
Nó chờ đợi một kết nối khách hàng. Bây giờ, hãy mở một cửa sổ hoặc dấu nhắc lệnh đầu cuối khác và chạy máy khách:
Trong cửa sổ máy chủ, bạn nên nhận thấy một cái gì đó như thế này:
Trong đầu ra ở trên, máy chủ đã in tuple 33 được trả về từ 34. Đây là địa chỉ IP của máy khách và số cổng TCP. Số cổng, 35, rất có thể sẽ khác nhau khi bạn chạy nó trên máy của bạn.Xem trạng thái ổ cắmĐể xem trạng thái hiện tại của ổ cắm trên máy chủ của bạn, hãy sử dụng 36. Nó có sẵn theo mặc định trên MacOS, Linux và Windows.Tại đây, đầu ra NetStat từ MacOS sau khi khởi động máy chủ:
Lưu ý rằng 37 là 38. Nếu 39 đã sử dụng 40 thay vì 41, NetStat sẽ hiển thị điều này: 0 37 là 43, có nghĩa là tất cả các giao diện máy chủ có sẵn hỗ trợ họ địa chỉ sẽ được sử dụng để chấp nhận các kết nối đến. Trong ví dụ này, 5 đã được sử dụng (IPv4) trong cuộc gọi đến 7. Bạn có thể thấy điều này trong cột 46: 47.Đầu ra ở trên được cắt để chỉ hiển thị máy chủ Echo. Bạn có thể thấy nhiều đầu ra hơn, tùy thuộc vào hệ thống mà bạn đang chạy nó. Những điều cần chú ý là các cột 46, 37 và 50. Trong ví dụ cuối cùng ở trên, NetStat cho thấy máy chủ Echo đang sử dụng ổ cắm IPv4 TCP ( 47), trên cổng 65432 trên tất cả các giao diện ( 43) và nó ở trạng thái nghe ( 53).
Một cách khác để truy cập này, cùng với thông tin hữu ích bổ sung, là sử dụng 54 (liệt kê các tệp mở). Nó có sẵn theo mặc định trên macOS và có thể được cài đặt trên Linux bằng cách sử dụng trình quản lý gói của bạn, nếu nó chưa có: 1 54 cung cấp cho bạn 56, 57 (ID quy trình) và 58 (ID người dùng) của ổ cắm Internet mở khi được sử dụng với tùy chọn 59. Trên đây là quá trình máy chủ Echo. 36 và 54 có sẵn nhiều tùy chọn và khác nhau tùy thuộc vào hệ điều hành mà bạn đang chạy chúng. Kiểm tra trang 62 hoặc tài liệu cho cả hai. Họ chắc chắn đáng để dành một ít thời gian với và làm quen. Bạn sẽ được khen thưởng. Trên macOS và Linux, sử dụng 63 và 64. Đối với Windows, sử dụng 65.Ở đây, một lỗi phổ biến mà bạn sẽ gặp phải khi một nỗ lực kết nối được thực hiện vào một cổng không có ổ cắm nghe: 2Số cổng được chỉ định là sai hoặc máy chủ đang chạy. Hoặc có thể có một tường lửa trên đường dẫn mà chặn kết nối, có thể dễ dàng quên đi. Bạn cũng có thể thấy lỗi 66. Nhận một quy tắc tường lửa được thêm vào cho phép khách hàng kết nối với cổng TCP!Có một danh sách các lỗi phổ biến trong phần tham chiếu. Sự cố giao tiếpBây giờ bạn sẽ xem xét kỹ hơn về cách máy khách và máy chủ giao tiếp với nhau: Khi sử dụng giao diện loopback (địa chỉ IPv4 9 hoặc địa chỉ IPv6 68), dữ liệu không bao giờ rời khỏi máy chủ hoặc chạm vào mạng bên ngoài. Trong sơ đồ trên, giao diện loopback được chứa bên trong máy chủ. Điều này thể hiện bản chất bên trong của giao diện loopback và cho thấy rằng các kết nối và dữ liệu quá cảnh là cục bộ đến máy chủ. Đây là lý do tại sao bạn cũng sẽ nghe thấy giao diện loopback và địa chỉ IP 9 hoặc 68 được gọi là Local localhost.Các ứng dụng sử dụng giao diện Loopback để liên lạc với các quy trình khác chạy trên máy chủ và để bảo mật và cách ly khỏi mạng bên ngoài. Bởi vì nó nội bộ và chỉ có thể truy cập từ bên trong máy chủ, nên nó không bị lộ. Bạn có thể thấy điều này trong hành động nếu bạn có một máy chủ ứng dụng sử dụng cơ sở dữ liệu riêng của nó. Nếu nó không phải là cơ sở dữ liệu được sử dụng bởi các máy chủ khác, thì nó có thể được cấu hình để nghe các kết nối trên giao diện Loopback. Nếu đây là trường hợp, các máy chủ khác trên mạng có thể kết nối với nó. Khi bạn sử dụng địa chỉ IP khác ngoài 9 hoặc 68 trong các ứng dụng của bạn, nó có thể bị ràng buộc với giao diện Ethernet mà kết nối với mạng bên ngoài. Đây là cửa ngõ của bạn đến các máy chủ khác bên ngoài vương quốc Local Localhost của bạn:Hãy cẩn thận ở ngoài đó. Nó là một thế giới khó chịu, độc ác. Hãy chắc chắn đọc phần bằng cách sử dụng tên máy chủ trước khi mạo hiểm từ giới hạn an toàn của địa phương. Có một ghi chú bảo mật áp dụng ngay cả khi bạn không sử dụng tên máy chủ nhưng chỉ sử dụng địa chỉ IP. Xử lý nhiều kết nốiMáy chủ Echo chắc chắn có những hạn chế của nó. Điều lớn nhất là nó chỉ phục vụ một khách hàng và sau đó thoát ra. Khách hàng Echo cũng có giới hạn này, nhưng có một vấn đề bổ sung. Khi khách hàng sử dụng 31, có thể nó sẽ chỉ trả về một byte, 74 từ 75: 3Đối số 76 của 04 được sử dụng ở trên là lượng dữ liệu tối đa được nhận cùng một lúc. Nó không có nghĩa là 4 sẽ trả lại 04 byte.Phương pháp 3 cũng hành xử theo cách này. Nó trả về số byte được gửi, có thể nhỏ hơn kích thước của dữ liệu được truyền vào. Bạn có trách nhiệm kiểm tra điều này và gọi 3 nhiều lần khi cần gửi tất cả dữ liệu:
Trong ví dụ trên, bạn đã tránh phải làm điều này bằng cách sử dụng 82:
Bạn có hai vấn đề vào thời điểm này:
Bạn có thể làm gì? Có nhiều cách tiếp cận để đồng thời. Một cách tiếp cận phổ biến là sử dụng I/O không đồng bộ. 86 đã được đưa vào thư viện tiêu chuẩn trong Python 3.4. Sự lựa chọn truyền thống là sử dụng chủ đề.Vấn đề với sự đồng thời là nó khó có thể đi đúng. Có nhiều sự tinh tế để xem xét và bảo vệ chống lại. Tất cả chỉ là một trong những điều này để thể hiện chính nó và ứng dụng của bạn có thể đột nhiên thất bại theo những cách không tinh tế. Điều này có nghĩa là khiến bạn sợ hãi khi học và sử dụng lập trình đồng thời. Nếu ứng dụng của bạn cần mở rộng quy mô, thì đó là một điều cần thiết nếu bạn muốn sử dụng nhiều hơn một bộ xử lý hoặc một lõi. Tuy nhiên, đối với hướng dẫn này, bạn sẽ sử dụng một cái gì đó mà thậm chí còn truyền thống hơn các chủ đề và dễ lý luận hơn. Bạn sẽ sử dụng ông nội của các cuộc gọi hệ thống: 87.Phương pháp 87 cho phép bạn kiểm tra hoàn thành I/O trên nhiều ổ cắm. Vì vậy, bạn có thể gọi 87 để xem ổ cắm nào có I/O sẵn sàng để đọc và/hoặc viết. Nhưng đây là Python, vì vậy có nhiều hơn nữa. Bạn sẽ sử dụng mô -đun bộ chọn trong thư viện tiêu chuẩn để việc triển khai hiệu quả nhất được sử dụng, bất kể hệ điều hành mà bạn tình cờ đang chạy:
Tuy nhiên, bằng cách sử dụng 87, bạn không thể chạy đồng thời. Điều đó nói rằng, tùy thuộc vào khối lượng công việc của bạn, phương pháp này có thể vẫn rất nhanh. Nó phụ thuộc vào những gì ứng dụng của bạn cần làm khi nó phục vụ một yêu cầu và số lượng khách hàng cần hỗ trợ. 86 sử dụng đa nhiệm hợp tác đơn luồng và vòng lặp sự kiện để quản lý các tác vụ. Với 87, bạn sẽ viết phiên bản của một vòng lặp sự kiện, mặc dù đơn giản và đồng bộ hơn. Khi sử dụng nhiều luồng, mặc dù bạn có đồng thời, hiện tại bạn phải sử dụng GIL (khóa phiên dịch toàn cầu) với CPython và Pypy. Điều này có hiệu quả giới hạn số lượng công việc bạn có thể làm song song.Đây là tất cả để nói rằng sử dụng 87 có thể là một lựa chọn hoàn toàn tốt. Don cảm thấy như bạn phải sử dụng 86, chủ đề hoặc thư viện không đồng bộ mới nhất. Thông thường, trong một ứng dụng mạng, ứng dụng của bạn dù sao cũng bị ràng buộc I/O: nó có thể đang chờ trên mạng cục bộ, cho các điểm cuối ở phía bên kia của mạng, cho đĩa ghi, v.v.Nếu bạn nhận được yêu cầu từ các khách hàng bắt đầu công việc ràng buộc CPU, hãy xem mô -đun đồng thời. Nó chứa lớp ProcessPoolExecutor, sử dụng một nhóm quy trình để thực hiện các cuộc gọi không đồng bộ. Nếu bạn sử dụng nhiều quy trình, hệ điều hành có thể lên lịch mã Python của bạn để chạy song song trên nhiều bộ xử lý hoặc lõi, mà không cần Gil. Để biết ý tưởng và cảm hứng, hãy xem Pycon Talk John Reese - Suy nghĩ bên ngoài Gil với Asyncio và Multiprocessing - Pycon 2018. Trong phần tiếp theo, bạn sẽ xem xét các ví dụ về một máy chủ và máy khách giải quyết các vấn đề này. Họ sử dụng 87 để xử lý đồng thời nhiều kết nối và gọi 3 và 4 bao nhiêu lần nếu cần.Máy khách và máy chủ đa kết nốiTrong hai phần tiếp theo, bạn sẽ tạo một máy chủ và máy khách xử lý nhiều kết nối bằng cách sử dụng đối tượng 98 được tạo từ mô -đun chọn lọc.Máy chủ đa kết nốiĐầu tiên, chuyển sự chú ý của bạn sang máy chủ đa kết nối. Phần đầu tiên thiết lập ổ cắm nghe: 4Sự khác biệt lớn nhất giữa máy chủ này và máy chủ Echo là cuộc gọi đến 99 để định cấu hình ổ cắm ở chế độ không chặn. Các cuộc gọi được thực hiện cho ổ cắm này sẽ không còn chặn. Khi nó được sử dụng với 00, như bạn sẽ thấy bên dưới, bạn có thể đợi các sự kiện trên một hoặc nhiều ổ cắm và sau đó đọc và ghi dữ liệu khi nó sẵn sàng. 01 đăng ký ổ cắm được theo dõi với 00 cho các sự kiện mà bạn quan tâm. Đối với ổ cắm nghe, bạn muốn đọc các sự kiện: 03.Để lưu trữ bất kỳ dữ liệu tùy ý nào mà bạn thích cùng với ổ cắm, bạn sẽ sử dụng 04. Nó đã trở lại khi 87 trở lại. Bạn sẽ sử dụng 04 để theo dõi những gì đã được gửi và nhận trên ổ cắm.Tiếp theo là vòng lặp sự kiện: 5 07 Khối cho đến khi có ổ cắm sẵn sàng cho I/O. Nó trả về một danh sách các bộ dữ liệu, một cho mỗi ổ cắm. Mỗi tuple chứa một 08 và 09. 08 là một selectorKey 11 chứa thuộc tính 12. 13 là đối tượng ổ cắm và 09 là mặt nạ sự kiện của các hoạt động đã sẵn sàng.Nếu 15 là 83, thì bạn sẽ biết nó từ ổ cắm nghe và bạn cần chấp nhận kết nối. Bạn sẽ gọi chức năng 17 của riêng bạn để lấy đối tượng ổ cắm mới và đăng ký nó bằng bộ chọn. Bạn sẽ nhìn vào điều đó trong một khoảnh khắc.Nếu 15 không phải là 83, thì bạn sẽ biết đó là một ổ cắm khách hàng mà Lừa đã được chấp nhận và bạn cần phải phục vụ nó. 20 sau đó được gọi với 08 và 09 làm đối số, và đó là mọi thứ bạn cần để vận hành trên ổ cắm.Đây là những gì chức năng 17 của bạn làm: 6Bởi vì ổ cắm nghe đã được đăng ký cho sự kiện 03, nên nó sẽ sẵn sàng để đọc. Bạn gọi 25 và sau đó gọi 26 để đặt ổ cắm ở chế độ không chặn.Hãy nhớ rằng, đây là mục tiêu chính trong phiên bản này của máy chủ vì bạn không muốn nó chặn. Nếu nó chặn, thì toàn bộ máy chủ bị đình trệ cho đến khi nó trở lại. Điều đó có nghĩa là các ổ cắm khác được chờ đợi mặc dù máy chủ không tích cực hoạt động. Đây là trạng thái Hang Hang đáng sợ mà bạn không muốn máy chủ của bạn được sử dụng. Tiếp theo, bạn tạo một đối tượng để giữ dữ liệu mà bạn muốn bao gồm cùng với ổ cắm bằng cách sử dụng 27. Bởi vì bạn muốn biết khi nào kết nối máy khách đã sẵn sàng để đọc và viết, cả hai sự kiện đó đều được đặt với bitwise hoặc toán tử: 7Mặt nạ 28, ổ cắm và đối tượng dữ liệu sau đó được truyền đến 01.Bây giờ hãy xem 20 để xem kết nối máy khách được xử lý như thế nào khi nó sẵn sàng: 8Đây là trung tâm của máy chủ đa kết nối đơn giản. 08 là 11 được trả về từ 87 có chứa đối tượng ổ cắm ( 12) và đối tượng dữ liệu. 09 chứa các sự kiện đã sẵn sàng.Nếu ổ cắm đã sẵn sàng để đọc, thì 36 sẽ đánh giá thành 37, do đó 38 được gọi. Bất kỳ dữ liệu nào mà đọc được được thêm vào 39 để nó có thể được gửi sau.Lưu ý khối 40 để kiểm tra xem không có dữ liệu nào được nhận: 9Nếu không nhận được dữ liệu, điều này có nghĩa là máy khách đã đóng ổ cắm của họ, vì vậy máy chủ cũng vậy. Nhưng don không quên gọi 41 trước khi đóng, vì vậy, nó không còn được theo dõi bởi 87.Khi ổ cắm đã sẵn sàng để viết, điều này phải luôn luôn là trường hợp của ổ cắm khỏe mạnh, bất kỳ dữ liệu nào nhận được được lưu trữ trong 39 đều được lặp lại với máy khách bằng cách sử dụng 44. Các byte được gửi sau đó được xóa khỏi bộ đệm gửi: 0Phương thức 3 trả về số byte được gửi. Số này sau đó có thể được sử dụng với ký hiệu lát cắt trên bộ đệm 46 để loại bỏ các byte được gửi.Máy khách đa kết nốiBây giờ hãy xem máy khách đa kết nối, 47. Nó rất giống với máy chủ, nhưng thay vì nghe các kết nối, nó bắt đầu bằng cách bắt đầu kết nối thông qua 48: 1 49 được đọc từ dòng lệnh và là số lượng kết nối để tạo cho máy chủ. Giống như máy chủ, mỗi ổ cắm được đặt thành chế độ không chặn.Bạn sử dụng 2 thay vì 1 vì 1 sẽ ngay lập tức tăng ngoại lệ 53. Phương thức 2 ban đầu trả về một chỉ báo lỗi, 55, thay vì nêu ra một ngoại lệ sẽ can thiệp vào kết nối đang diễn ra. Sau khi kết nối hoàn thành, ổ cắm đã sẵn sàng để đọc và viết và được trả lại bởi 87.Sau khi ổ cắm được thiết lập, dữ liệu bạn muốn lưu trữ với ổ cắm được tạo bằng 27. Các tin nhắn mà máy khách sẽ gửi đến máy chủ được sao chép bằng 58 vì mỗi kết nối sẽ gọi 59 và sửa đổi danh sách. Mọi thứ cần thiết để theo dõi những gì khách hàng cần gửi, đã gửi và nhận được, bao gồm tổng số byte trong tin nhắn, được lưu trữ trong đối tượng 04.Kiểm tra các thay đổi được thực hiện từ máy chủ ____ ____220 cho phiên bản máy khách: 2Nó về cơ bản giống nhau nhưng đối với một sự khác biệt quan trọng. Máy khách theo dõi số lượng byte mà nó nhận được từ máy chủ để có thể đóng bên cạnh kết nối. Khi máy chủ phát hiện ra điều này, nó cũng đóng mặt của kết nối. Lưu ý rằng bằng cách thực hiện điều này, máy chủ phụ thuộc vào máy khách được hành động tốt: máy chủ hy vọng máy khách sẽ đóng phía kết nối của nó khi nó thực hiện gửi tin nhắn. Nếu máy khách không đóng, máy chủ sẽ để kết nối mở. Trong một ứng dụng thực sự, bạn có thể muốn bảo vệ chống lại điều này trong máy chủ của mình bằng cách triển khai thời gian chờ để ngăn chặn các kết nối máy khách tích lũy nếu họ không gửi yêu cầu sau một khoảng thời gian nhất định. Chạy máy khách và máy chủ đa kết nốiBây giờ, thời gian để chạy 62 và 47. Cả hai đều sử dụng các đối số dòng lệnh. Bạn có thể chạy chúng mà không cần đối số để xem các tùy chọn.Đối với máy chủ, hãy vượt qua số 7 và 00: 3Đối với máy khách, cũng chuyển số lượng kết nối để tạo cho máy chủ, 66: 4Dưới đây là đầu ra của máy chủ khi nghe trên giao diện loopback trên cổng 65432: 5Dưới đây là đầu ra của máy khách khi nó tạo hai kết nối với máy chủ ở trên: 6Tuyệt quá! Bây giờ bạn đã chạy máy khách và máy chủ đa kết nối. Trong phần tiếp theo, bạn sẽ lấy ví dụ này hơn nữa. Ứng dụng khách hàng và máy chủVí dụ về máy khách và máy chủ đa kết nối chắc chắn là một cải tiến so với nơi bạn bắt đầu. Tuy nhiên, bây giờ bạn có thể thực hiện thêm một bước và giải quyết các thiếu sót của ví dụ 67 trước đó trong một triển khai cuối cùng: máy khách và máy chủ ứng dụng.Bạn muốn một máy khách và máy chủ xử lý các lỗi một cách thích hợp để các kết nối khác bị ảnh hưởng. Rõ ràng, khách hàng hoặc máy chủ của bạn không nên rơi xuống trong một quả bóng giận dữ nếu một ngoại lệ không bị bắt. Đây là điều mà bạn đã phải lo lắng cho đến bây giờ, bởi vì các ví dụ đã cố tình bỏ qua việc xử lý lỗi cho sự ngắn gọn và rõ ràng. Bây giờ, bạn đã quen thuộc với API cơ bản, ổ cắm không chặn và 87, bạn có thể thêm một số xử lý lỗi và giải quyết con voi trong phòng, mà các ví dụ đã giấu bạn đằng sau bức màn lớn ở đó. Hãy nhớ rằng lớp tùy chỉnh đã được đề cập trở lại trong phần giới thiệu? Đó là những gì bạn sẽ khám phá tiếp theo.Đầu tiên, bạn sẽ giải quyết các lỗi:
Vì vậy, một điều bạn cần làm là bắt 69. Một cân nhắc quan trọng khác liên quan đến lỗi là thời gian chờ. Bạn sẽ thấy họ được thảo luận ở nhiều nơi trong tài liệu. Thời gian chờ xảy ra và là một lỗi được gọi là lỗi bình thường. Máy chủ và bộ định tuyến được khởi động lại, các cổng chuyển đổi xấu, dây cáp trở nên xấu, dây cáp bị rút phích cắm, bạn đặt tên cho nó. Bạn nên chuẩn bị cho những lỗi này và các lỗi khác, xử lý chúng trong mã của bạn.timeouts. You’ll see them discussed in many places in the documentation. Timeouts happen and are a so-called normal error. Hosts and routers are rebooted, switch ports go bad, cables go bad, cables get unplugged, you name it. You should be prepared for these and other errors, handling them in your code.Còn con voi trong phòng thì sao? Như được gợi ý bởi loại ổ cắm 7, khi sử dụng TCP, bạn đã đọc từ một dòng byte liên tục. Nó giống như đọc từ một tệp trên đĩa, nhưng thay vào đó, bạn đã đọc các byte từ mạng. Tuy nhiên, không giống như đọc một tệp, ở đó không có 72.Nói cách khác, bạn có thể định vị lại vị trí con trỏ ổ cắm, nếu có một, và di chuyển xung quanh dữ liệu. Khi byte đến ổ cắm của bạn, có bộ đệm mạng liên quan. Một khi bạn đã đọc chúng, chúng cần được lưu ở đâu đó, nếu không bạn sẽ bỏ chúng. Gọi 4 một lần nữa đọc luồng byte tiếp theo có sẵn từ ổ cắm.Bạn sẽ đọc từ ổ cắm trong các khối. Vì vậy, bạn cần gọi 4 và lưu dữ liệu trong bộ đệm cho đến khi bạn đọc đủ byte để có một thông báo hoàn chỉnh có ý nghĩa với ứng dụng của bạn.Nó tùy thuộc vào bạn để xác định và theo dõi vị trí của các ranh giới thông điệp. Theo như ổ cắm TCP, nó chỉ gửi và nhận các byte thô đến và từ mạng. Nó không biết gì về những byte thô đó có nghĩa là gì. Đây là lý do tại sao bạn cần xác định giao thức lớp ứng dụng. Những gì một giao thức lớp ứng dụng? Nói một cách đơn giản, ứng dụng của bạn sẽ gửi và nhận tin nhắn. Định dạng của các tin nhắn này là giao thức ứng dụng của bạn. Nói cách khác, độ dài và định dạng mà bạn chọn cho các thông báo này xác định ngữ nghĩa và hành vi của ứng dụng của bạn. Điều này liên quan trực tiếp đến những gì bạn đã học trong đoạn trước về việc đọc byte từ ổ cắm. Khi bạn đọc các byte với 4, bạn cần theo kịp số lượng byte đã được đọc và tìm ra ranh giới thông điệp ở đâu.Làm thế nào bạn có thể làm điều này? Một cách là luôn luôn gửi tin nhắn có độ dài cố định. Nếu họ luôn luôn có cùng kích thước, thì nó dễ dàng. Khi bạn đọc số byte đó vào bộ đệm, thì bạn biết bạn có một tin nhắn đầy đủ. Tuy nhiên, việc sử dụng các tin nhắn có độ dài cố định là không hiệu quả cho các tin nhắn nhỏ nơi bạn cần sử dụng đệm để điền vào chúng. Ngoài ra, bạn vẫn còn để lại vấn đề phải làm gì về dữ liệu không phù hợp với một tin nhắn. Trong hướng dẫn này, bạn sẽ học được một cách tiếp cận chung, một cách mà sử dụng bởi nhiều giao thức, bao gồm cả HTTP. Bạn có thể các tin nhắn tiền tố có tiêu đề bao gồm độ dài nội dung cũng như bất kỳ trường nào khác bạn cần. Bằng cách này, bạn sẽ chỉ cần theo kịp tiêu đề. Khi bạn đã đọc tiêu đề, bạn có thể xử lý nó để xác định độ dài của nội dung tin nhắn. Với độ dài nội dung, sau đó bạn có thể đọc số byte đó để tiêu thụ nó.header that includes the content length as well as any other fields you need. By doing this, you’ll only need to keep up with the header. Once you’ve read the header, you can process it to determine the length of the message’s content. With the content length, you can then read that number of bytes to consume it. Bạn sẽ thực hiện điều này bằng cách tạo một lớp tùy chỉnh có thể gửi và nhận tin nhắn có chứa dữ liệu văn bản hoặc nhị phân. Bạn có thể cải thiện và mở rộng lớp này cho các ứng dụng của riêng bạn. Điều quan trọng nhất là bạn sẽ có thể thấy một ví dụ về cách thực hiện điều này. Trước khi bạn bắt đầu, có một cái gì đó bạn cần biết về ổ cắm và byte. Như bạn đã học trước đó, khi gửi và nhận dữ liệu qua ổ cắm, bạn đã gửi và nhận các byte thô. Nếu bạn nhận được dữ liệu và muốn sử dụng nó trong một bối cảnh mà nó được giải thích là nhiều byte, ví dụ như một số nguyên 4 byte, bạn sẽ cần phải tính đến rằng nó có thể ở định dạng mà không có nguồn gốc từ máy CPU của bạn. Máy khách hoặc máy chủ ở đầu bên kia có thể có CPU sử dụng đơn đặt hàng byte khác với của bạn. Nếu đây là trường hợp, thì bạn sẽ cần phải chuyển đổi nó sang thứ tự byte gốc của máy chủ trước khi sử dụng nó. Thứ tự byte này được gọi là một endianness CPU. Xem byte endianness trong phần tham chiếu để biết chi tiết. Bạn sẽ tránh được vấn đề này bằng cách tận dụng Unicode cho tiêu đề tin nhắn của bạn và sử dụng UTF-8 mã hóa. Vì UTF-8 sử dụng mã hóa 8 bit, không có vấn đề đặt hàng byte nào. Bạn có thể tìm thấy một lời giải thích trong mã hóa Python và tài liệu Unicode. Lưu ý rằng điều này chỉ áp dụng cho tiêu đề văn bản. Bạn sẽ sử dụng một loại rõ ràng và mã hóa được xác định trong tiêu đề cho nội dung mà Lừa được gửi, tải trọng tin nhắn. Điều này sẽ cho phép bạn chuyển bất kỳ dữ liệu nào mà bạn thích (văn bản hoặc nhị phân), ở bất kỳ định dạng nào. Bạn có thể dễ dàng xác định thứ tự byte của máy bằng cách sử dụng 76. Ví dụ, bạn có thể thấy một cái gì đó như thế này: 7Nếu bạn chạy điều này trong một máy ảo mô phỏng CPU lớn (PowerPC), thì một cái gì đó như thế này sẽ xảy ra: 8Trong ứng dụng ví dụ này, giao thức lớp ứng dụng của bạn định nghĩa tiêu đề là văn bản Unicode với mã hóa UTF-8. Đối với nội dung thực tế trong tin nhắn, tải trọng tin nhắn, bạn sẽ vẫn phải trao đổi thứ tự byte theo cách thủ công nếu cần. Điều này sẽ phụ thuộc vào ứng dụng của bạn và liệu nó có cần xử lý dữ liệu nhị phân đa byte từ một máy có độ chính xác khác hay không. Bạn có thể giúp khách hàng hoặc máy chủ của mình triển khai hỗ trợ nhị phân bằng cách thêm các tiêu đề bổ sung và sử dụng chúng để truyền các tham số, tương tự như HTTP. Don Tiết lo lắng nếu điều này không có ý nghĩa gì. Trong phần tiếp theo, bạn sẽ thấy tất cả những điều này hoạt động và phù hợp với nhau như thế nào. Gửi tin nhắn ứng dụngVẫn còn một chút vấn đề. Bạn có một tiêu đề có độ dài thay đổi, rất đẹp và linh hoạt, nhưng làm thế nào để bạn biết độ dài của tiêu đề khi đọc nó với 4?Khi bạn đã biết trước đây về việc sử dụng 4 và ranh giới tin nhắn, bạn cũng đã học được rằng các tiêu đề có độ dài cố định có thể không hiệu quả. Điều đó đúng, nhưng bạn sẽ sử dụng một tiêu đề nhỏ, 2 byte, có độ dài cố định để có tiền tố tiêu đề JSON chứa độ dài của nó.Bạn có thể nghĩ về điều này như một cách tiếp cận lai để gửi tin nhắn. Trên thực tế, bạn đã khởi động quá trình nhận thông báo bằng cách gửi độ dài của tiêu đề trước. Điều này giúp người nhận của bạn dễ dàng giải mã thông điệp. Để cung cấp cho bạn ý tưởng tốt hơn về định dạng tin nhắn, hãy xem toàn bộ tin nhắn: Một thông báo bắt đầu với một tiêu đề có độ dài cố định của hai byte, là một số nguyên theo thứ tự byte mạng. Đây là độ dài của tiêu đề tiếp theo, tiêu đề JSON có độ dài thay đổi. Khi bạn đã đọc hai byte với 4, thì bạn biết bạn có thể xử lý hai byte dưới dạng số nguyên và sau đó đọc số byte đó trước khi giải mã tiêu đề UTF-8 JSON.Tiêu đề JSON chứa một từ điển của các tiêu đề bổ sung. Một trong số đó là 80, đó là số byte của nội dung tin nhắn (không bao gồm tiêu đề JSON). Khi bạn đã gọi 4 và đọc byte 80, sau đó bạn đã đạt đến một ranh giới tin nhắn, có nghĩa là bạn đã đọc toàn bộ tin nhắn.Lớp thông báo ứng dụngCuối cùng, tiền thưởng! Trong phần này, bạn sẽ nghiên cứu lớp 83 và xem cách mà nó được sử dụng với 87 khi đọc và viết các sự kiện xảy ra trên ổ cắm.Ứng dụng ví dụ này phản ánh những loại tin nhắn mà máy khách và máy chủ có thể sử dụng hợp lý. Bạn vượt xa khách hàng và máy chủ đồ chơi Echo tại thời điểm này! Để giữ cho mọi thứ đơn giản và vẫn chứng minh mọi thứ sẽ hoạt động như thế nào trong một ứng dụng thực, ví dụ này sử dụng giao thức ứng dụng thực hiện một tính năng tìm kiếm cơ bản. Máy khách gửi yêu cầu tìm kiếm và máy chủ thực hiện tìm kiếm một trận đấu. Nếu yêu cầu được gửi bởi khách hàng được công nhận là tìm kiếm, máy chủ giả định rằng đó là một yêu cầu nhị phân và trả về phản hồi nhị phân. Sau khi đọc các phần sau, chạy các ví dụ và thử nghiệm mã, bạn sẽ thấy mọi thứ hoạt động như thế nào. Sau đó, bạn có thể sử dụng lớp 83 làm điểm bắt đầu và sửa đổi nó cho mục đích sử dụng của riêng bạn.Ứng dụng này không xa so với ví dụ máy khách và máy chủ 67. Mã vòng lặp sự kiện vẫn giữ nguyên trong 87 và 88. Những gì bạn sẽ làm là chuyển mã tin nhắn vào một lớp có tên 83 và thêm các phương thức để hỗ trợ đọc, viết và xử lý các tiêu đề và nội dung. Đây là một ví dụ tuyệt vời để sử dụng một lớp.Như bạn đã biết trước đây và bạn sẽ thấy bên dưới, làm việc với các ổ cắm liên quan đến việc giữ trạng thái. Bằng cách sử dụng một lớp, bạn giữ tất cả trạng thái, dữ liệu và mã được gói cùng nhau trong một đơn vị có tổ chức. Một thể hiện của lớp được tạo cho mỗi ổ cắm trong máy khách và máy chủ khi kết nối được bắt đầu hoặc chấp nhận. Lớp chủ yếu giống nhau cho cả máy khách và máy chủ cho các phương thức trình bao bọc và tiện ích. Họ bắt đầu với một dấu gạch dưới, như 90. Các phương pháp này đơn giản hóa làm việc với lớp. Họ giúp đỡ các phương pháp khác bằng cách cho phép chúng ngắn hơn và hỗ trợ nguyên tắc khô.Lớp máy chủ ____ ____283 hoạt động theo cách tương tự như máy khách và ngược lại. Sự khác biệt là máy khách bắt đầu kết nối và gửi thông báo yêu cầu, theo sau là xử lý thông báo phản hồi máy chủ. Ngược lại, máy chủ chờ kết nối, xử lý thông báo yêu cầu của máy khách và sau đó gửi tin nhắn phản hồi. Có vẻ như thế này:
Người phục vụ
Điểm vào tin nhắnHiểu cách thức hoạt động của lớp 83 có thể là một thách thức bởi vì có một khía cạnh của thiết kế của nó có thể không rõ ràng ngay lập tức. Tại sao? Quản lý trạng thái.Sau khi một đối tượng 83 được tạo, nó liên kết với một ổ cắm mà theo dõi các sự kiện bằng cách sử dụng 04: 9Khi các sự kiện đã sẵn sàng trên ổ cắm, họ đã được trả lại bởi 05. Sau đó, bạn có thể lấy lại tham chiếu trở lại đối tượng tin nhắn bằng thuộc tính 04 trên đối tượng 08 và gọi một phương thức trong 83: 0Nhìn vào vòng lặp sự kiện ở trên, bạn sẽ thấy rằng 00 nằm ở ghế lái. Nó chặn, chờ đợi ở đầu vòng lặp cho các sự kiện. Nó có trách nhiệm thức dậy khi đọc và viết các sự kiện đã sẵn sàng để được xử lý trên ổ cắm. Điều đó có nghĩa là, một cách gián tiếp, nó cũng chịu trách nhiệm gọi phương thức 10. Đó là lý do tại sao 10 là điểm nhập cảnh.Ở đây, những gì phương pháp 10 làm: 1Điều đó tốt: 10 rất đơn giản. Nó chỉ có thể làm hai điều: Gọi 14 và 15.Đây là nơi quản lý trạng thái xuất hiện. Nếu một phương pháp khác phụ thuộc vào các biến trạng thái có một giá trị nhất định, thì chúng sẽ chỉ được gọi từ 14 và 15. Điều này giữ cho logic đơn giản nhất có thể như các sự kiện xuất hiện trên ổ cắm để xử lý.Bạn có thể bị cám dỗ sử dụng hỗn hợp một số phương thức kiểm tra các biến trạng thái hiện tại và, tùy thuộc vào giá trị của chúng, hãy gọi các phương thức khác để xử lý dữ liệu bên ngoài 14 hoặc 15. Cuối cùng, điều này có thể sẽ chứng minh quá phức tạp để quản lý và theo kịp.Bạn chắc chắn nên sửa đổi lớp cho phù hợp với nhu cầu của riêng bạn để nó phù hợp nhất với bạn, nhưng có lẽ bạn sẽ có kết quả tốt nhất nếu bạn kiểm tra trạng thái và các cuộc gọi đến các phương thức phụ thuộc vào trạng thái đó với các phương thức 14 và 15 nếu có thể.Bây giờ hãy nhìn vào 14. Đây là phiên bản máy chủ, nhưng máy khách là như nhau. Nó chỉ sử dụng một tên phương thức khác, 23 thay vì 24: 2Phương pháp 25 được gọi là đầu tiên. Nó gọi 26 để đọc dữ liệu từ ổ cắm và lưu trữ trong bộ đệm nhận.Hãy nhớ rằng khi 26 được gọi, tất cả các dữ liệu tạo nên một tin nhắn hoàn chỉnh có thể chưa đến. 26 có thể cần được gọi lại. Đây là lý do tại sao có kiểm tra trạng thái cho từng phần của tin nhắn trước khi phương thức thích hợp để xử lý nó được gọi.Trước khi một phương thức xử lý một phần của tin nhắn, trước tiên nó kiểm tra để đảm bảo đủ byte đã được đọc vào bộ đệm nhận. Nếu họ có, nó xử lý các byte tương ứng của nó, sẽ loại bỏ chúng khỏi bộ đệm và ghi đầu ra của nó vào một biến mà Lọ sử dụng bởi giai đoạn xử lý tiếp theo. Vì có ba thành phần cho một tin nhắn, có ba kiểm tra trạng thái và các cuộc gọi phương thức 29:
Tiếp theo, kiểm tra 15. Đây là phiên bản máy chủ của máy chủ: 3Phương pháp 15 kiểm tra trước cho 38. Nếu một người tồn tại và một phản hồi đã được tạo ra, 39 sẽ được gọi. Phương thức 39 đặt biến trạng thái 41 và ghi phản hồi cho bộ đệm gửi.Phương thức 42 gọi 59 nếu có dữ liệu trong bộ đệm gửi.Hãy nhớ rằng khi 59 được gọi, tất cả dữ liệu trong bộ đệm gửi có thể không được xếp hàng để truyền. Các bộ đệm mạng cho ổ cắm có thể đầy và 59 có thể cần được gọi lại. Đây là lý do tại sao có kiểm tra nhà nước. Phương pháp 39 chỉ nên được gọi là một lần, nhưng nó dự kiến rằng 42 sẽ cần được gọi là nhiều lần.Phiên bản máy khách của 15 là tương tự: 4Vì máy khách bắt đầu kết nối với máy chủ và gửi yêu cầu trước, biến trạng thái 49 được kiểm tra. Nếu một yêu cầu đã được xếp hàng, nó sẽ gọi 50. Phương thức 51 tạo yêu cầu và ghi nó vào bộ đệm gửi. Nó cũng đặt biến trạng thái 49 để nó chỉ được gọi một lần.Giống như đối với máy chủ, 42 gọi 59 nếu có dữ liệu trong bộ đệm gửi.Sự khác biệt đáng chú ý trong phiên bản 15 của máy khách là lần kiểm tra cuối cùng để xem liệu yêu cầu đã được xếp hàng. Điều này sẽ được giải thích nhiều hơn trong tập lệnh chính của khách hàng, nhưng lý do cho điều này là để nói với 05 để ngừng giám sát ổ cắm cho các sự kiện ghi. Nếu yêu cầu đã được xếp hàng và bộ đệm gửi trống, thì bạn đã viết xong và bạn chỉ quan tâm đến các sự kiện đọc. Không có lý do gì để được thông báo rằng ổ cắm có thể ghi được.Để kết thúc phần này, hãy xem xét suy nghĩ này: Mục đích chính của phần này là giải thích rằng 05 đang gọi vào lớp 83 thông qua phương pháp 10 và để mô tả cách quản lý trạng thái.Điều này rất quan trọng vì 10 sẽ được gọi là nhiều lần trong suốt cuộc đời của kết nối. Do đó, hãy đảm bảo rằng bất kỳ phương thức nào chỉ nên được gọi một lần đều được kiểm tra một biến trạng thái hoặc biến trạng thái được đặt theo phương thức đều được người gọi kiểm tra.Kịch bản chính của máy chủTrong tập lệnh chính của máy chủ 88, các đối số được đọc từ dòng lệnh chỉ định giao diện và cổng để nghe: 5Ví dụ: để nghe trên giao diện loopback trên cổng 62, nhập: 6Sử dụng một chuỗi trống cho 63 để nghe trên tất cả các giao diện.Sau khi tạo ổ cắm, một cuộc gọi được thực hiện đến 64 với tùy chọn 65:
7Đặt tùy chọn ổ cắm này tránh lỗi 66. Bạn sẽ thấy điều này khi khởi động máy chủ trên một cổng có các kết nối ở trạng thái Time_Wait.Ví dụ: nếu máy chủ chủ động đóng kết nối, nó sẽ vẫn ở trạng thái 67 trong hai phút trở lên, tùy thuộc vào hệ điều hành. Nếu bạn cố gắng khởi động lại máy chủ trước khi trạng thái 67 hết hạn, thì bạn sẽ nhận được ngoại lệ 69 là 66. Đây là một biện pháp bảo vệ để đảm bảo rằng bất kỳ gói nào bị trì hoãn trong mạng không được cung cấp cho ứng dụng sai.Vòng lặp sự kiện bắt gặp bất kỳ lỗi nào để máy chủ có thể ở lại và tiếp tục chạy: 8Khi kết nối máy khách được chấp nhận, đối tượng 83 được tạo: 9Đối tượng 83 được liên kết với ổ cắm trong cuộc gọi đến 01 và ban đầu được đặt để chỉ theo dõi các sự kiện đọc. Khi yêu cầu đã được đọc, bạn sẽ sửa đổi nó để chỉ nghe các sự kiện ghi.Một lợi thế của việc thực hiện phương pháp này trong máy chủ là trong hầu hết các trường hợp, khi một ổ cắm khỏe mạnh và không có vấn đề về mạng, nó sẽ luôn có thể ghi được. Nếu bạn đã nói 01 cũng theo dõi 75, thì vòng lặp sự kiện sẽ ngay lập tức thức dậy và thông báo cho bạn rằng đây là trường hợp. Tuy nhiên, tại thời điểm này, không có lý do gì để thức dậy và gọi 3 trên ổ cắm. Không có phản hồi nào để gửi, bởi vì một yêu cầu chưa được xử lý. Điều này sẽ tiêu thụ và chất thải chu kỳ CPU có giá trị.Lớp tin nhắn máy chủTrong phần Nhập thông báo, bạn đã tìm hiểu cách đối tượng 83 được gọi là hành động khi các sự kiện ổ cắm đã sẵn sàng thông qua 10. Bây giờ bạn sẽ tìm hiểu những gì xảy ra khi dữ liệu được đọc trên ổ cắm và một thành phần hoặc mảnh của thông báo đã sẵn sàng để được máy chủ xử lý.Lớp thông báo máy chủ có trong 97, là một phần của mã nguồn bạn đã tải xuống trước đó. Bạn cũng có thể tải xuống mã bằng cách nhấp vào liên kết bên dưới:Các phương thức xuất hiện trong lớp theo thứ tự mà việc xử lý diễn ra cho một tin nhắn. Khi máy chủ đã đọc ít nhất hai byte, tiêu đề có độ dài cố định có thể được xử lý: 0Tiêu đề có độ dài cố định là một số nguyên 2 byte trong mạng, hoặc đơn đặt hàng Big-endian, byte. Nó chứa chiều dài của tiêu đề JSON. Bạn sẽ sử dụng struct.unpack () để đọc giá trị, giải mã nó và lưu trữ nó trong 31. Sau khi xử lý phần của thông báo mà nó chịu trách nhiệm, 81 sẽ loại bỏ nó khỏi bộ đệm nhận.Giống như với tiêu đề có độ dài cố định, khi có đủ dữ liệu trong bộ đệm nhận để chứa tiêu đề JSON, nó cũng có thể được xử lý: 1Phương pháp 82 được gọi để giải mã và giảm giá tiêu đề JSON vào từ điển. Bởi vì tiêu đề JSON được định nghĩa là unicode với mã hóa UTF-8, 83 được mã hóa cứng trong cuộc gọi. Kết quả được lưu vào 33. Sau khi xử lý phần của thông báo mà nó chịu trách nhiệm, 32 sẽ loại bỏ nó khỏi bộ đệm nhận.Tiếp theo là nội dung thực tế, hoặc tải trọng của tin nhắn. Nó được mô tả bởi tiêu đề JSON trong 33. Khi 80 byte có sẵn trong bộ đệm nhận, yêu cầu có thể được xử lý: 2Sau khi lưu nội dung tin nhắn vào biến 04, 24 sẽ xóa nó khỏi bộ đệm nhận. Sau đó, nếu loại nội dung là JSON, 24 giải mã và giải mã nó. Nếu nó không, ứng dụng ví dụ này giả định rằng nó là một yêu cầu nhị phân và chỉ cần in loại nội dung.Điều cuối cùng 24 không phải là sửa đổi bộ chọn để chỉ giám sát các sự kiện ghi. Trong tập lệnh chính của máy chủ, 88, ổ cắm ban đầu được đặt để giám sát các sự kiện đọc. Bây giờ yêu cầu đã được xử lý đầy đủ, bạn không còn quan tâm đến việc đọc.Một phản hồi bây giờ có thể được tạo và ghi vào ổ cắm. Khi ổ cắm có thể ghi, 39 được gọi từ 15: 3Một phản hồi được tạo bằng cách gọi các phương thức khác, tùy thuộc vào loại nội dung. Trong ứng dụng ví dụ này, việc tra cứu từ điển đơn giản được thực hiện cho các yêu cầu JSON khi 95. Đối với các ứng dụng của riêng bạn, bạn có thể xác định các phương pháp khác được gọi ở đây.Sau khi tạo thông báo phản hồi, biến trạng thái 96 được đặt sao cho 15 không gọi lại 39. Cuối cùng, phản hồi được thêm vào bộ đệm gửi. Điều này được nhìn thấy và gửi qua 42.Một chút khó để tìm ra là làm thế nào để đóng kết nối sau khi phản hồi được viết. Bạn có thể thực hiện cuộc gọi đến 5 trong phương thức 42: 4Mặc dù nó hơi ẩn, nhưng đây là một sự đánh đổi có thể chấp nhận được khi lớp 83 chỉ xử lý một tin nhắn trên mỗi kết nối. Sau khi phản hồi được viết, không còn gì để máy chủ làm. Nó đã hoàn thành công việc của mình.Tập lệnh chính của khách hàngTrong tập lệnh chính của máy khách, 87, các đối số được đọc từ dòng lệnh và được sử dụng để tạo yêu cầu và khởi động kết nối với máy chủ: 5Đây là một ví dụ: 6Sau khi tạo một từ điển đại diện cho yêu cầu từ các đối số dòng lệnh, máy chủ, cổng và từ điển yêu cầu được chuyển đến 04: 7Một ổ cắm được tạo cho kết nối máy chủ, cũng như đối tượng 83 bằng từ điển 38.Giống như đối với máy chủ, đối tượng 83 được liên kết với ổ cắm trong cuộc gọi đến 01. Tuy nhiên, đối với máy khách, ổ cắm ban đầu được thiết lập để được theo dõi cho cả các sự kiện đọc và viết. Khi yêu cầu đã được viết, bạn sẽ sửa đổi nó để chỉ nghe các sự kiện đọc.Cách tiếp cận này mang lại cho bạn lợi thế tương tự như máy chủ: không lãng phí chu kỳ CPU. Sau khi yêu cầu đã được gửi, bạn không còn quan tâm đến các sự kiện viết, vì vậy, không có lý do gì để thức dậy và xử lý chúng. Lớp tin nhắn khách hàngTrong phần Nhập thông báo, bạn đã tìm hiểu làm thế nào đối tượng tin nhắn được gọi là hành động khi các sự kiện ổ cắm đã sẵn sàng thông qua 10. Bây giờ bạn sẽ tìm hiểu những gì xảy ra sau khi dữ liệu được đọc và ghi trên ổ cắm và một thông báo đã sẵn sàng để được xử lý bởi máy khách.Lớp tin nhắn của máy khách nằm trong 00, là một phần của mã nguồn bạn đã tải xuống trước đó. Bạn cũng có thể tải xuống mã bằng cách nhấp vào liên kết bên dưới:Các phương thức xuất hiện trong lớp theo thứ tự mà việc xử lý diễn ra cho một tin nhắn. Nhiệm vụ đầu tiên cho khách hàng là xếp hàng yêu cầu:
8Các từ điển được sử dụng để tạo yêu cầu, tùy thuộc vào những gì được truyền trên dòng lệnh, nằm trong tập lệnh chính của máy khách, 87. Từ điển yêu cầu được truyền như một đối số cho lớp khi một đối tượng 83 được tạo.Thông báo yêu cầu được tạo và thêm vào bộ đệm gửi, sau đó được nhìn thấy và gửi qua 42. Biến trạng thái 14 được đặt sao cho 50 được gọi lại.Sau khi yêu cầu đã được gửi, máy khách chờ phản hồi từ máy chủ. Các phương thức đọc và xử lý một thông báo trong máy khách giống như đối với máy chủ. Vì dữ liệu phản hồi được đọc từ ổ cắm, các phương thức tiêu đề 29 được gọi là: 81 và 18.Sự khác biệt là trong việc đặt tên của các phương pháp 29 cuối cùng và thực tế là họ xử lý một phản hồi, không tạo ra một: 23, 21 và 22.Cuối cùng, nhưng chắc chắn không kém phần quan trọng, là cuộc gọi cuối cùng cho 23: 9
Lớp thông báo kết thúcĐể kết thúc việc học của bạn về lớp 83, điều đáng nói là một vài điều quan trọng cần chú ý với một vài phương pháp hỗ trợ.Bất kỳ trường hợp ngoại lệ nào được đưa ra bởi lớp đều bị bắt bởi tập lệnh chính trong Điều khoản 25 bên trong vòng lặp sự kiện: 0Lưu ý dòng: 26.Đây là một dòng thực sự quan trọng, vì nhiều lý do! Nó không chỉ đảm bảo rằng ổ cắm được đóng, mà 26 cũng loại bỏ ổ cắm khỏi được theo dõi bởi 87. Điều này đơn giản hóa rất nhiều mã trong lớp và giảm độ phức tạp. Nếu có một ngoại lệ hoặc bạn tự nâng cao một cách rõ ràng, bạn sẽ biết 5 sẽ chăm sóc việc dọn dẹp.Các phương pháp 30 và 31 cũng chứa một cái gì đó thú vị: 1Lưu ý dòng 32.Phương pháp 42 cũng có một. Những dòng này rất quan trọng vì chúng bắt được một lỗi tạm thời và bỏ qua nó bằng 34. Lỗi tạm thời là khi ổ cắm sẽ chặn, ví dụ nếu nó chờ đợi trên mạng hoặc đầu kia của kết nối, còn được gọi là ngang hàng của nó.Bằng cách bắt và bỏ qua ngoại lệ với 34, 87 cuối cùng sẽ kích hoạt một cuộc gọi mới và bạn sẽ có một cơ hội khác để đọc hoặc viết dữ liệu.Chạy máy khách và máy chủ ứng dụngSau tất cả những công việc khó khăn này, đó là thời gian để có một số niềm vui và chạy một số tìm kiếm! Trong các ví dụ này, bạn sẽ chạy máy chủ để nó lắng nghe trên tất cả các giao diện bằng cách chuyển một chuỗi trống cho đối số 7. Điều này sẽ cho phép bạn chạy máy khách và kết nối từ một máy ảo mà trên mạng khác. Nó mô phỏng một máy PowerPC lớn.Đầu tiên, khởi động máy chủ: 2Bây giờ chạy máy khách và nhập tìm kiếm. Xem nếu bạn có thể tìm thấy anh ấy: 3Bạn có thể nhận thấy rằng thiết bị đầu cuối đang chạy một shell mà sử dụng mã hóa văn bản của Unicode (UTF-8), do đó, đầu ra trên in độc đáo với biểu tượng cảm xúc. Bây giờ xem bạn có thể tìm thấy những chú chó con không: 4Lưu ý chuỗi byte được gửi qua mạng cho yêu cầu trong dòng 38. Nó dễ dàng hơn để xem nếu bạn tìm kiếm các byte được in bằng hex đại diện cho biểu tượng cảm xúc chó con: 39. Nếu thiết bị đầu cuối của bạn đang sử dụng Unicode với UTF-8 mã hóa, bạn sẽ có thể nhập biểu tượng cảm xúc để tìm kiếm.Điều này chứng tỏ rằng bạn đã gửi các byte thô qua mạng và chúng cần được giải mã bởi người nhận để được giải thích chính xác. Đây là lý do tại sao bạn đã đi đến tất cả những rắc rối để tạo một tiêu đề chứa loại nội dung và mã hóa. Ở đây, đầu ra máy chủ từ cả hai kết nối máy khách ở trên: 5Nhìn vào dòng 38 để xem các byte được ghi vào ổ cắm của máy khách. Đây là thông báo phản hồi của máy chủ.Bạn cũng có thể kiểm tra gửi các yêu cầu nhị phân đến máy chủ nếu đối số 41 là bất cứ điều gì khác ngoài 42: 6Bởi vì yêu cầu 43 không phải là 44, máy chủ coi nó là một loại nhị phân tùy chỉnh và không thực hiện giải mã JSON. Nó chỉ đơn giản là in 43 và trả về mười byte đầu tiên cho máy khách: 7Xử lý sự cốChắc chắn, một cái gì đó đã giành được công việc, và bạn sẽ tự hỏi phải làm gì. Đừng lo lắng, nó xảy ra với tất cả mọi người. Hy vọng rằng, với sự giúp đỡ của hướng dẫn này, trình gỡ lỗi của bạn và công cụ tìm kiếm yêu thích của bạn, bạn sẽ có thể đi lại với phần mã nguồn. Nếu không, điểm dừng đầu tiên của bạn phải là tài liệu mô -đun ổ cắm Python. Hãy chắc chắn rằng bạn đọc tất cả các tài liệu cho từng hàm hoặc phương thức mà bạn gọi. Ngoài ra, đọc qua phần tham chiếu dưới đây cho các ý tưởng. Đặc biệt, kiểm tra phần lỗi. Đôi khi, nó không phải là tất cả về mã nguồn. Mã nguồn có thể chính xác và nó chỉ là máy chủ khác, máy khách hoặc máy chủ. Hoặc nó có thể là mạng. Có thể một bộ định tuyến, tường lửa hoặc một số thiết bị mạng khác đang chơi người đàn ông. Đối với các loại vấn đề này, các công cụ bổ sung là rất cần thiết. Dưới đây là một vài công cụ và tiện ích có thể giúp hoặc ít nhất là cung cấp một số manh mối. Ping 46 sẽ kiểm tra xem máy chủ có còn sống và kết nối với mạng hay không bằng cách gửi yêu cầu Echo ICMP. Nó giao tiếp trực tiếp với ngăn xếp giao thức TCP/IP của hệ điều hành, do đó, nó hoạt động độc lập với bất kỳ ứng dụng nào chạy trên máy chủ.Dưới đây là một ví dụ về việc chạy ping trên macOS: 8Lưu ý các số liệu thống kê ở cuối đầu ra. Điều này có thể hữu ích khi bạn đang cố gắng khám phá các vấn đề kết nối không liên tục. Ví dụ, có mất gói nào không? Có bao nhiêu độ trễ? Bạn có thể kiểm tra thời gian khứ hồi. Nếu có một tường lửa giữa bạn và máy chủ khác, một yêu cầu Echo Ping có thể không được phép. Một số quản trị viên tường lửa thực hiện các chính sách thực thi điều này. Ý tưởng là họ không muốn chủ nhà của họ có thể phát hiện được. Nếu đây là trường hợp và bạn có các quy tắc tường lửa được thêm vào để cho phép các máy chủ giao tiếp, thì hãy đảm bảo rằng các quy tắc cũng cho phép ICMP vượt qua giữa chúng. ICMP là giao thức được sử dụng bởi 46, nhưng nó cũng là giao thức TCP và các giao thức cấp thấp khác sử dụng để truyền đạt các thông báo lỗi. Nếu bạn trải nghiệm hành vi kỳ lạ hoặc kết nối chậm, đây có thể là lý do.Tin nhắn ICMP được xác định theo loại và mã. Để cung cấp cho bạn một ý tưởng về thông tin quan trọng mà họ mang theo, đây là một số ít:
Xem bài viết MTU Discovery để biết thông tin liên quan đến phân mảnh và tin nhắn ICMP. Đây là một ví dụ về một cái gì đó có thể gây ra hành vi kỳ lạ. netstatTrong phần xem trạng thái ổ cắm, bạn đã tìm hiểu cách 36 có thể được sử dụng để hiển thị thông tin về ổ cắm và trạng thái hiện tại của chúng. Tiện ích này có sẵn trên MacOS, Linux và Windows.Phần đó đã không đề cập đến các cột 49 và 50 trong đầu ra ví dụ. Các cột này sẽ cho bạn thấy số lượng byte được giữ trong bộ đệm mạng được xếp hàng để truyền hoặc nhận, nhưng vì một số lý do, thiên đường đã được đọc hoặc viết bởi ứng dụng từ xa hoặc cục bộ.Nói cách khác, các byte đang chờ đợi trong bộ đệm mạng trong hàng đợi hệ điều hành. Một lý do có thể là ứng dụng bị ràng buộc CPU hoặc không thể gọi 26 hoặc 59 và xử lý byte. Hoặc có thể có các vấn đề mạng ảnh hưởng đến truyền thông, như tắc nghẽn hoặc phần cứng mạng bị hỏng hoặc cáp.Để chứng minh điều này và xem bạn có thể gửi bao nhiêu dữ liệu trước khi thấy lỗi, bạn có thể thử máy khách thử nghiệm kết nối với máy chủ thử nghiệm và liên tục gọi 59. Máy chủ thử nghiệm không bao giờ gọi 26. Nó chỉ chấp nhận kết nối. Điều này khiến các bộ đệm mạng trên máy chủ điền, cuối cùng làm tăng lỗi trên máy khách.Đầu tiên, khởi động máy chủ: 9Sau đó, chạy máy khách để xem lỗi là gì: 0Tại đây, ____ ____136 đầu ra từ trong khi máy khách và máy chủ vẫn đang chạy, với máy khách in thông báo lỗi trên nhiều lần: 1Mục đầu tiên là máy chủ ( 37 có cổng 65432): 2Lưu ý 49: 58.Mục thứ hai là máy khách ( 59 có cổng 65432): 3Lưu ý 50: 61.Khách hàng chắc chắn đang cố gắng viết byte, nhưng máy chủ không phải là đọc chúng. Điều này đã khiến hàng đợi bộ đệm mạng máy chủ điền vào phía nhận và hàng đợi bộ đệm mạng của máy khách để điền vào phía gửi. các cửa sổNếu bạn làm việc với Windows, có một bộ tiện ích mà bạn chắc chắn nên kiểm tra xem bạn có chưa sử dụng được không: Windows SysiNternals. Một trong số đó là 62. TCPVIEW là một đồ họa 36 cho Windows. Ngoài địa chỉ, số cổng và trạng thái ổ cắm, nó sẽ cho bạn thấy bạn chạy tổng số cho số lượng gói và byte được gửi và nhận. Giống như với tiện ích UNIX 54, bạn cũng nhận được tên quy trình và ID. Kiểm tra các menu cho các tùy chọn hiển thị khác.WIRESHARKĐôi khi bạn cần phải xem những gì xảy ra trên dây. Quên về những gì nhật ký ứng dụng nói hoặc giá trị là gì mà được trả lại từ một cuộc gọi thư viện. Bạn muốn xem những gì thực sự được gửi hoặc nhận trên mạng. Cũng giống như với những người gỡ lỗi, khi bạn cần nhìn thấy nó, không có sự thay thế nào. Wireshark là một máy phân tích giao thức mạng và ứng dụng thu thập lưu lượng chạy trên macOS, Linux và Windows, trong số các phân tích khác. Có một phiên bản GUI có tên 65 và cũng là một phiên bản dựa trên văn bản, có tên là 66.Chạy thu thập lưu lượng truy cập là một cách tuyệt vời để xem cách ứng dụng hoạt động trên mạng và thu thập bằng chứng về những gì nó gửi và nhận, và tần suất và bao nhiêu. Bạn cũng có thể thấy khi khách hoặc máy chủ đóng hoặc hủy bỏ kết nối hoặc ngừng phản hồi. Thông tin này có thể cực kỳ hữu ích khi bạn xử lý sự cố. Có nhiều hướng dẫn tốt và các tài nguyên khác trên web sẽ hướng dẫn bạn những điều cơ bản của việc sử dụng Wireshark và Tshark. Dưới đây, một ví dụ về việc bắt giữ lưu lượng truy cập bằng cách sử dụng Wireshark trên giao diện Loopback: Ở đây, ví dụ tương tự được hiển thị ở trên bằng cách sử dụng 66: 4Tiếp theo, bạn sẽ nhận được nhiều tài liệu tham khảo hơn để hỗ trợ hành trình lập trình ổ cắm của bạn! Tài liệu tham khảoBạn có thể sử dụng phần này làm tài liệu tham khảo chung với thông tin bổ sung và liên kết đến các tài nguyên bên ngoài. Tài liệu Python
LỗiSau đây là từ tài liệu mô -đun Python từ 68:
Dưới đây là một số lỗi phổ biến mà bạn có thể gặp phải khi làm việc với ổ cắm:
Ổ cắm địa chỉ gia đình 5 và 75 đại diện cho các họ địa chỉ và giao thức được sử dụng cho đối số đầu tiên đến 6. API sử dụng một địa chỉ mong đợi nó ở một định dạng nhất định, tùy thuộc vào việc ổ cắm được tạo bằng 5 hay 75.
Lưu ý đoạn trích bên dưới từ tài liệu mô -đun ổ cắm Python sườn liên quan đến giá trị 7 của bộ địa chỉ:
Xem tài liệu gia đình ổ cắm Python sườn để biết thêm thông tin. Hướng dẫn này sử dụng ổ cắm IPv4, nhưng nếu mạng của bạn hỗ trợ nó, hãy thử kiểm tra và sử dụng IPv6 nếu có thể. Một cách để hỗ trợ điều này một cách dễ dàng là bằng cách sử dụng ổ cắm chức năng.getaddrinfo (). Nó dịch các đối số 7 và 00 thành một chuỗi năm bộ phận chứa tất cả các đối số cần thiết để tạo ổ cắm được kết nối với dịch vụ đó. 02 sẽ hiểu và giải thích các địa chỉ IPv6 và tên máy chủ được truyền vào địa chỉ IPv6, ngoài IPv4.Ví dụ sau trả về thông tin địa chỉ cho kết nối TCP với 03 trên cổng 04:>>> 5Kết quả có thể khác nhau trên hệ thống của bạn nếu IPv6 được bật. Các giá trị được trả về ở trên có thể được sử dụng bằng cách chuyển chúng cho 6 và 06. Có một ví dụ về máy khách và máy chủ trong phần ví dụ của tài liệu mô -đun ổ cắm Python.Sử dụng tên máy chủĐối với ngữ cảnh, phần này áp dụng chủ yếu cho việc sử dụng tên máy chủ với 8 và 1 hoặc 2, khi bạn có ý định sử dụng giao diện Loopback, thì Local Localhost. Tuy nhiên, nó cũng áp dụng bất cứ lúc nào bạn sử dụng tên máy chủ và có một kỳ vọng về việc nó giải quyết đến một địa chỉ nhất định và có ý nghĩa đặc biệt đối với ứng dụng của bạn ảnh hưởng đến hành vi hoặc giả định của nó. Điều này trái ngược với kịch bản điển hình của máy khách bằng cách sử dụng tên máy chủ để kết nối với máy chủ mà DNS giải quyết bởi DNS, như www.example.com.Sau đây là từ tài liệu mô -đun Python từ 68:
Quy ước tiêu chuẩn cho tên là Local LocalHost, để nó giải quyết thành 9 hoặc 68, giao diện Loopback. Điều này sẽ nhiều khả năng là trường hợp của bạn trên hệ thống của bạn, nhưng có thể không. Nó phụ thuộc vào cách hệ thống của bạn được cấu hình để giải quyết tên. Như với tất cả những điều đó, luôn có những ngoại lệ và không có gì đảm bảo rằng việc sử dụng tên là Local Localhost, sẽ kết nối với giao diện Loopback.Ví dụ: trên Linux, xem 13, tệp cấu hình chuyển đổi dịch vụ tên. Một nơi khác để kiểm tra MacOS và Linux là tệp 14. Trên Windows, xem 15. Tệp 16 chứa một bảng tĩnh của ánh xạ tên-địa chỉ ở định dạng văn bản đơn giản. DNS là một phần khác của câu đố hoàn toàn.Điều thú vị là, tính đến tháng 6 năm 2018, có một bản nháp của RFC cho phép ‘Localhost, được địa phương thảo luận về các công ước, giả định và bảo mật xung quanh việc sử dụng tên là Local Localhost. Điều quan trọng để hiểu là khi bạn sử dụng tên máy chủ trong ứng dụng của mình, các địa chỉ được trả lại theo nghĩa đen có thể là bất cứ điều gì. Don Tiết đưa ra các giả định liên quan đến một tên nếu bạn có một ứng dụng nhạy cảm với bảo mật. Tùy thuộc vào ứng dụng và môi trường của bạn, điều này có thể hoặc không phải là mối quan tâm đối với bạn. Bất kể bạn có sử dụng tên máy chủ hay không, nếu ứng dụng của bạn cần hỗ trợ các kết nối an toàn thông qua mã hóa và xác thực, thì bạn có thể muốn xem xét sử dụng TLS. Đây là chủ đề riêng của nó và ngoài phạm vi của hướng dẫn này. Xem tài liệu mô -đun SSL Python sườn để bắt đầu. Đây là cùng một giao thức mà trình duyệt web của bạn sử dụng để kết nối an toàn với các trang web. Với giao diện, địa chỉ IP và độ phân giải tên để xem xét, có nhiều biến. Những gì bạn nên làm? Dưới đây là một số khuyến nghị mà bạn có thể sử dụng nếu bạn không có quy trình xem xét ứng dụng mạng:
Giao diện Ethernet Sử dụng một địa chỉ IP, chẳng hạn như with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: pass # Use the socket object without calling s.close(). 06. Để hỗ trợ nhiều giao diện, hãy sử dụng một chuỗi trống cho tất cả các giao diện/địa chỉ. Xem ghi chú bảo mật ở trên.Khách hàng Sử dụng địa chỉ IP để thống nhất và không phụ thuộc vào độ phân giải tên. Đối với trường hợp điển hình, sử dụng tên máy chủ. Xem ghi chú bảo mật ở trên. Đối với máy khách hoặc máy chủ, nếu bạn cần xác thực máy chủ mà bạn đang kết nối, hãy xem xét sử dụng TLS. Chặn các cuộc gọi Một hàm hoặc phương thức tạm thời tạm dừng ứng dụng của bạn là một cuộc gọi chặn. Ví dụ, $ python echo-client.py Received b'Hello, world' 0, $ python echo-client.py Received b'Hello, world' 1, $ python echo-client.py Received b'Hello, world' 3 và $ python echo-client.py Received b'Hello, world' 4, có nghĩa là họ không trả lại ngay lập tức. Chặn các cuộc gọi phải chờ trên các cuộc gọi hệ thống (I/O) để hoàn thành trước khi chúng có thể trả về một giá trị. Vì vậy, bạn, người gọi, bị chặn cho đến khi họ đã hoàn thành hoặc thời gian chờ hoặc lỗi khác xảy ra.Chặn các cuộc gọi ổ cắm có thể được đặt thành chế độ không chặn để chúng quay lại ngay lập tức. Nếu bạn làm điều này, thì bạn sẽ cần ít nhất phải tái cấu trúc hoặc thiết kế lại ứng dụng của mình để xử lý thao tác ổ cắm khi nó sẵn sàng. Bởi vì cuộc gọi trả về ngay lập tức, dữ liệu có thể chưa sẵn sàng. Callee đang chờ đợi trên mạng và đã có thời gian để hoàn thành công việc của mình. Nếu đây là trường hợp, thì trạng thái hiện tại là giá trị 70 27. Chế độ không chặn được hỗ trợ với .setblocking ().Theo mặc định, ổ cắm luôn được tạo ở chế độ chặn. Xem ghi chú về thời gian chờ ổ cắm để biết mô tả của ba chế độ. Đóng kết nốiMột điều thú vị cần lưu ý với TCP là nó hoàn toàn hợp pháp cho máy khách hoặc máy chủ để đóng phía kết nối của họ trong khi phía bên kia vẫn mở. Điều này được gọi là kết nối nửa mở của người Viking. Nó đưa ra quyết định của ứng dụng cho dù điều này có mong muốn hay không. Nói chung, nó không. Ở trạng thái này, phía đã đóng phần cuối của kết nối không còn có thể gửi dữ liệu. Họ chỉ có thể nhận được nó. Cách tiếp cận này không nhất thiết phải được khuyến nghị, nhưng ví dụ, HTTP sử dụng tiêu đề có tên là Kết nối, kết nối mà sử dụng để chuẩn hóa cách các ứng dụng nên đóng hoặc tồn tại các kết nối mở. Để biết chi tiết, xem Phần 6.3 trong RFC 7230, Giao thức chuyển siêu văn bản (http/1.1): cú pháp và định tuyến tin nhắn. Khi thiết kế và viết ứng dụng của bạn và giao thức lớp ứng dụng của nó, đó là một ý tưởng tốt để tiếp tục và tìm ra cách bạn mong đợi các kết nối sẽ được đóng lại. Đôi khi điều này là hiển nhiên và đơn giản, hoặc nó là một thứ gì đó có thể lấy một số mẫu và thử nghiệm ban đầu. Nó phụ thuộc vào ứng dụng và cách vòng lặp tin nhắn được xử lý với dữ liệu dự kiến. Chỉ cần đảm bảo rằng các ổ cắm luôn được đóng một cách kịp thời sau khi họ hoàn thành công việc của họ. Điều này trở nên có vấn đề khi có dữ liệu liên quan đến việc lưu trữ trong các tệp hoặc cơ sở dữ liệu và ở đó, không có siêu dữ liệu nào có sẵn chỉ định mã hóa của nó. Khi dữ liệu được chuyển sang điểm cuối khác, nó sẽ phải cố gắng phát hiện mã hóa. Để thảo luận, xem bài viết của Wikipedia, Unicode, trong đó tham chiếu RFC 3629: UTF-8, định dạng chuyển đổi của ISO 10646:
Việc thực hiện từ đây là luôn luôn lưu trữ mã hóa được sử dụng cho dữ liệu mà xử lý bởi ứng dụng của bạn nếu nó có thể thay đổi. Nói cách khác, hãy cố gắng bằng cách nào đó lưu trữ mã hóa dưới dạng siêu dữ liệu nếu nó không phải lúc nào cũng UTF-8 hoặc một số mã hóa khác với BOM. Sau đó, bạn có thể gửi mã hóa đó trong một tiêu đề cùng với dữ liệu để cho người nhận biết nó là gì. Đặt hàng byte được sử dụng trong TCP/IP là Big-Endian và được gọi là thứ tự mạng. Thứ tự mạng được sử dụng để biểu diễn số nguyên trong các lớp thấp hơn của ngăn xếp giao thức, như địa chỉ IP và số cổng. Mô -đun ổ cắm Python Python bao gồm các chức năng chuyển đổi số nguyên thành và từ mạng và đơn đặt hàng byte:
Bạn cũng có thể sử dụng mô -đun struct để đóng gói và giải nén dữ liệu nhị phân bằng các chuỗi định dạng: 6Sự kết luậnBạn đã đề cập rất nhiều nền tảng trong hướng dẫn này! Mạng và ổ cắm là những chủ đề lớn. Nếu bạn mới sử dụng mạng hoặc ổ cắm, thì hãy không được khuyến khích bởi tất cả các thuật ngữ và từ viết tắt. Có rất nhiều phần để làm quen với để hiểu cách mọi thứ hoạt động cùng nhau. Tuy nhiên, giống như Python, nó sẽ bắt đầu có ý nghĩa hơn khi bạn biết các mảnh riêng lẻ và dành nhiều thời gian hơn với chúng. Trong hướng dẫn này, bạn:
Từ đây, bạn có thể sử dụng lớp tùy chỉnh của mình và xây dựng nó để tìm hiểu và giúp tạo ra các ứng dụng ổ cắm của riêng bạn dễ dàng và nhanh hơn. Để xem lại các ví dụ, bạn có thể nhấp vào liên kết bên dưới: Chúc mừng bạn đã đến cùng! Bây giờ bạn đang trên đường sử dụng ổ cắm trong các ứng dụng của riêng bạn. Chúc may mắn trên hành trình phát triển ổ cắm của bạn. |