<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Python 套接字教程 > 原文: [http://zetcode.com/python/socket/](http://zetcode.com/python/socket/) Python 套接字教程展示了如何使用套接字進行 Python 網絡編程。 套接字編程是低級的。 本教程的目的是介紹包括這些低級詳細信息的網絡編程。 有更高級的 Python API,例如 Twisted,可能更適合。 在編程中,套接字是網絡上運行的兩個程序之間通信的端點。 套接字用于在客戶端程序和服務器程序之間創建連接。 Python 的`socket`模塊提供了與 Berkeley 套接字 API 的接口。 > **注意**:在網絡中,“套接字”一詞具有不同的含義。 它用于 IP 地址和端口號的組合。 ## 網絡協議 TCP/IP 是設備用于在互聯網和大多數本地網絡上進行通信的一組協議。 TCP 更可靠,具有大量錯誤檢查并需要更多資源。 HTTP,SMTP 或 FTP 等服務使用它。 UDP 的可靠性要差得多,錯誤檢查的能力也有限,所需資源也更少。 VoIP 等服務使用它。 `socket.SOCK_STREAM`用于為 TCP 創建套接字,而`socket.SOCK_DGRAM`為 UDP 創建套接字。 ## 地址族 創建套接字時,必須指定其地址族。 然后,我們只能在套接字中使用該類型的地址。 * `AF_UNIX`,`AF_LOCAL` - 本地通訊 * `AF_INET` - IPv4 互聯網協議 * `AF_INET6` - IPv6 互聯網協議 * `AF_IPX` - IPX-Novell 協議 * `AF_BLUETOOTH` - 無線藍牙協議 * `AF_PACKET` - 底層數據包接口 對于`AF_INET`地址族,指定了一對(主機,端口)。 `host`是一個字符串,表示互聯網域表示法中的主機名(如`example.com`)或 IPv4 地址(如`93.184.216.34`),并且`port`是整數。 ## Python 獲取 IP 地址 使用`gethostbyname()`,我們獲得主機的 IP 地址。 `get_ip.py` ```py #!/usr/bin/env python import socket ip = socket.gethostbyname('example.com') print(ip) ``` 該示例打印`example.com`的 IP 地址。 ```py $ ./get_ip.py 93.184.216.34 ``` 這是輸出。 ## Python UDP 套接字示例 UDP 是一種通信協議,它通過網絡傳輸獨立的數據包,不保證到達且也不保證傳遞順序。 使用 UDP 的一項服務是每日報價(QOTD)。 `qotd_client.py` ```py #!/usr/bin/env python import socket with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: message = b'' addr = ("djxmmx.net", 17) s.sendto(message, addr) data, address = s.recvfrom(1024) print(data.decode()) ``` 該示例創建一個連接到 QOTD 服務的客戶端程序。 ```py import socket ``` 我們導入`socket`模塊。 ```py with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: ``` 創建了用于 IPv4 的數據報套接字。 ```py message = b'' ``` 我們發送空消息; QOTD 服務通過向套接字發送任意數據來工作; 它只是用引號引起來。 為了通過 TCP/UDP 進行通信,我們使用二進制字符串。 ```py addr = ("djxmmx.net", 17) ``` 我們提供地址和端口。 ```py s.sendto(message, addr) ``` 我們使用`sendto()`方法發送數據。 ```py data, address = s.recvfrom(1024) ``` UDP 套接字使用`recvfrom()`接收數據。 它的參數是緩沖區大小。 返回值是一對(數據,地址),其中數據是代表接收到的數據的字節字符串,而地址是發送數據的套接字的地址。 ```py print(data.decode()) ``` 我們將解碼后的數據打印到終端。 ```py $ ./qotd_client.py "Oh the nerves, the nerves; the mysteries of this machine called man! Oh the little that unhinges it, poor creatures that we are!" Charles Dickens (1812-70) ``` 這是一個示例輸出。 ## Python TCP 套接字示例 是提供當前時間的服務器。 客戶端無需任何命令即可直接連接到服務器,服務器以當前時間作為響應。 > **注意**:時間服務器來來往往,因此我們可能需要在 <https://www.ntppool.org/en/> 上找到可用的服務器。 `time_client.py` ```py #!/usr/bin/env python import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: host = "time.nist.gov" port = 13 s.connect((host, port)) s.sendall(b'') print(str(s.recv(4096), 'utf-8')) ``` 該示例通過連接到時間服務器的 TCP 套接字來確定當前時間。 ```py with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: ``` 創建用于 IPv4 的 TCP 套接字。 ```py host = "time.nist.gov" port = 13 ``` 這是工作時間服務器的主機名和端口號。 ```py s.connect((host, port)) ``` 我們使用`connect()`連接到遠程套接字。 ```py s.sendall(b'') ``` `sendall()`方法將數據發送到套接字。 套接字必須連接到遠程套接字。 它繼續從字節發送數據,直到發送完所有數據或發生錯誤為止。 ```py print(str(s.recv(4096), 'utf-8')) ``` 我們打印接收到的數據。 `recv()`方法從套接字接收最多`buffersize`個字節。 當沒有數據可用時,它將阻塞,直到至少一個字節可用或直到遠端關閉為止。 當遠端關閉并讀取所有數據時,它將返回一個空字節字符串。 ## Python 套接字 HEAD 請求 HEAD 請求是沒有消息正文的 GET 請求。 請求/響應的標頭包含元數據,例如 HTTP 協議版本或內容類型。 `head_request.py` ```py #!/usr/bin/env python import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect(("webcode.me" , 80)) s.sendall(b"HEAD / HTTP/1.1\r\nHost: webcode.me\r\nAccept: text/html\r\n\r\n") print(str(s.recv(1024), 'utf-8')) ``` 在示例中,我們向`webcode.me`發送 HEAD 請求。 ```py s.sendall(b"HEAD / HTTP/1.1\r\nHost: webcode.me\r\nAccept: text/html\r\n\r\n") ``` 用`HEAD`命令發出頭請求,后跟資源 URL 和 HTTP 協議版本。 請注意,`\r\n`是通信過程中必不可少的部分。 在 [RFC 7231](https://tools.ietf.org/html/rfc7231) 文檔中描述了詳細信息。 ```py $ head_request.py HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Sun, 08 Sep 2019 11:23:25 GMT Content-Type: text/html Content-Length: 348 Last-Modified: Sat, 20 Jul 2019 11:49:25 GMT Connection: keep-alive ETag: "5d32ffc5-15c" Accept-Ranges: bytes ``` 這是輸出。 ## Python 套接字 GET 請求 HTTP GET 方法請求指定資源的表示形式。 使用 GET 的請求應僅檢索數據。 `get_request.py` ```py #!/usr/bin/env python import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect(("webcode.me" , 80)) s.sendall(b"GET / HTTP/1.1\r\nHost: webcode.me\r\nAccept: text/html\r\nConnection: close\r\n\r\n") while True: data = s.recv(1024) if not data: break print(data.decode()) ``` 該示例使用 GET 請求讀取`webcode.me`的主頁。 ```py s.sendall(b"GET / HTTP/1.1\r\nHost: webcode.me\r\nAccept: text/html\r\nConnection: close\r\n\r\n") ``` 對于 HTTP 1.1 協議,默認情況下,連接可以是持久的。 這就是為什么我們發送`Connection: close`標頭的原因。 ```py while True: data = s.recv(1024) if not data: break print(data.decode()) ``` 我們使用`while`循環來處理接收到的數據。 如果沒有錯誤發生,則`recv()`返回接收到的字節。 如果連接已正常關閉,則返回值為空字節字符串。 `recv()`是一種阻止方法,直到完成它,或者達到超時或發生另一個異常為止。 ```py $ ./get_request.py HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Sun, 08 Sep 2019 11:39:34 GMT Content-Type: text/html Content-Length: 348 Last-Modified: Sat, 20 Jul 2019 11:49:25 GMT Connection: keep-alive ETag: "5d32ffc5-15c" Access-Control-Allow-Origin: * Accept-Ranges: bytes <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My html page</title> </head> <body> <p> Today is a beautiful day. We go swimming and fishing. </p> <p> Hello there. How are you? </p> </body> </html> ``` 這是輸出。 ## 回顯客戶端服務器示例 回顯服務器將來自客戶端的消息發送回去。 這是用于測試和學習的經典示例。 `echo_server.py` ```py #!/usr/bin/env python import socket import time with socket.socket() as s: host = 'localhost' port = 8001 s.bind((host, port)) print(f'socket binded to {port}') s.listen() con, addr = s.accept() with con: while True: data = con.recv(1024) if not data: break con.sendall(data) ``` 回顯服務器將客戶端消息發送回客戶端。 ```py host = 'localhost' port = 8001 ``` 服務器在端口 8001 上的 localhost 上運行。 ```py s.bind((host, port)) ``` `bind()`方法建立通信端點。 它將套接字綁定到指定的地址。 套接字必須尚未綁定。 (地址的格式取決于地址系列。) ```py s.listen() ``` `listen()`方法使服務器可以接受連接。 服務器現在可以監聽套接字上的連接。 `listen()`具有`backlog`參數。 它指定系統在拒絕新連接之前允許的不可接受的連接數。 自 Python 3.5 起,此參數是可選的。 如果未指定,則選擇默認的積壓值。 ```py con, addr = s.accept() ``` 使用`accept()`,服務器接受連接。 它阻止并等待傳入??連接。 套接字必須綁定到一個地址并監聽連接。 返回值是一對`(con, addr)`,其中`con`是可用于在連接上發送和接收數據的新套接字對象,而`addr`是綁定到連接另一端上的套接字的地址。 請注意,`accept()`創建了一個新的套接字,用于與客戶端進行通信,該套接字與監聽套接字不同。 `echo_client.py` ```py #!/usr/bin/env python import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: host = "localhost" port = 8001 s.connect((host, port)) s.sendall(b'hello there') print(str(s.recv(4096), 'utf-8')) ``` 客戶端將消息發送到回顯服務器。 ## 異步服務器示例 為了提高服務器的性能,我們可以使用`asyncio`模塊。 `async_server.py` ```py #!/usr/bin/env python # from threading import current_thread import asyncio async def handle_client(reader, writer): data = (await reader.read(1024)) writer.write(data) writer.close() loop = asyncio.get_event_loop() loop.create_task(asyncio.start_server(handle_client, 'localhost', 8001)) loop.run_forever() ``` 現在,我們可以測試阻塞服務器和非阻塞服務器的性能。 ```py $ ab -c 50 -n 1000 http://localhost:8001/ ``` 例如,我們可以使用 Apache 基準測試工具測試性能。 在我們的例子中,命令發送 1000 個請求,一次發送 50 個。 在本教程中,我們展示了如何在 Python 中使用套接字創建簡單的網絡程序。 您可能也對以下相關教程感興趣: [Python 字符串](/lang/python/strings/), [Python Jinja 教程](/python/jinja/)和 [Python 教程](/lang/python/),或列出[所有 Python 教程](/all/#python)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看