<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
匯入 socket 模組 import socket
建立使用者端 socket 物件 socket.socket(AddressFamily, Type)
引數說明:
方法說明:
import socket if __name__ == '__main__': # 建立tcp使用者端通訊端 # 1. AF_INET:表示ipv4 # 2. SOCK_STREAM: tcp傳輸協定 tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 和伺服器端應用程式建立連線 tcp_client_socket.connect(("192.168.131.62", 8080)) # 程式碼執行到此,說明連線建立成功 # 準備傳送的資料 send_data = "你好伺服器端,我是使用者端小黑!".encode("gbk") # 傳送資料 tcp_client_socket.send(send_data) # 接收資料, 這次接收的資料最大位元組數是1024 recv_data = tcp_client_socket.recv(1024) # 返回的直接是伺服器端程式傳送的二進位制資料 print(recv_data) # 對資料進行解碼 recv_content = recv_data.decode("gbk") print("接收伺服器端的資料為:", recv_content) # 關閉通訊端 tcp_client_socket.close()
b'hello'
接收伺服器端的資料為: hello
說明
網路偵錯助手充當伺服器端程式:
匯入 socket 模組
import socket
建立伺服器端 socket 物件
socket.socket(AddressFamily, Type)
引數說明:
方法說明:
import socket if __name__ == '__main__': # 建立tcp伺服器端通訊端 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 設定埠號複用,讓程式退出埠號立即釋放 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 給程式繫結埠號 tcp_server_socket.bind(("", 8989)) # 設定監聽 # 128:最大等待建立連線的個數, 提示: 目前是單任務的伺服器端,同一時刻只能服務與一個使用者端,後續使用多工能夠讓伺服器端同時服務與多個使用者端, # 不需要讓使用者端進行等待建立連線 # listen後的這個通訊端只負責接收使用者端連線請求,不能收發訊息,收發訊息使用返回的這個新通訊端來完成 tcp_server_socket.listen(128) # 等待使用者端建立連線的請求, 只有使用者端和伺服器端建立連線成功程式碼才會解阻塞,程式碼才能繼續往下執行 # 1. 專門和使用者端通訊的通訊端: service_client_socket # 2. 使用者端的ip地址和埠號: ip_port service_client_socket, ip_port = tcp_server_socket.accept() # 程式碼執行到此說明連線建立成功 print("使用者端的ip地址和埠號:", ip_port) # 接收使用者端傳送的資料, 這次接收資料的最大位元組數是1024 recv_data = service_client_socket.recv(1024) # 獲取資料的長度 recv_data_length = len(recv_data) print("接收資料的長度為:", recv_data_length) # 對二進位制資料進行解碼 recv_content = recv_data.decode("gbk") print("接收使用者端的資料為:", recv_content) # 準備傳送的資料 send_data = "ok, 問題正在處理中...".encode("gbk") # 傳送資料給使用者端 service_client_socket.send(send_data) # 關閉服務與使用者端的通訊端, 終止和使用者端通訊的服務 service_client_socket.close() # 關閉伺服器端的通訊端, 終止和使用者端提供建立連線請求的服務 tcp_server_socket.close()
執行結果:
使用者端的ip地址和埠號: ('172.16.47.209', 52472)
接收資料的長度為: 5
接收使用者端的資料為: hello
說明:
解決辦法有兩種:
更換伺服器端埠號設定埠號複用(推薦大家使用),也就是說讓伺服器端程式退出後埠號立即釋放。
設定埠號複用的程式碼如下:
# 引數1: 表示當前通訊端 # 引數2: 設定埠號複用選項 # 引數3: 設定埠號複用選項對應的值 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
目前我們開發的TCP伺服器端程式只能服務於一個使用者端,如何開發一個多工版的TCP伺服器端程式能夠服務於多個使用者端呢?
完成多工,可以使用執行緒,比程序更加節省記憶體資源。
import socket import threading # 處理使用者端的請求操作 def handle_client_request(service_client_socket, ip_port): # 迴圈接收使用者端傳送的資料 while True: # 接收使用者端傳送的資料 recv_data = service_client_socket.recv(1024) # 容器型別判斷是否有資料可以直接使用if語句進行判斷,如果容器型別裡面有資料表示條件成立,否則條件失敗 # 容器型別: 列表、字典、元組、字串、set、range、二進位制資料 if recv_data: print(recv_data.decode("gbk"), ip_port) # 回覆 service_client_socket.send("ok,問題正在處理中...".encode("gbk")) else: print("使用者端下線了:", ip_port) break # 終止和使用者端進行通訊 service_client_socket.close() if __name__ == '__main__': # 建立tcp伺服器端通訊端 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 設定埠號複用,讓程式退出埠號立即釋放 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 繫結埠號 tcp_server_socket.bind(("", 9090)) # 設定監聽, listen後的通訊端是被動通訊端,只負責接收使用者端的連線請求 tcp_server_socket.listen(128) # 迴圈等待接收使用者端的連線請求 while True: # 等待接收使用者端的連線請求 service_client_socket, ip_port = tcp_server_socket.accept() print("使用者端連線成功:", ip_port) # 當用戶端和伺服器端建立連線成功以後,需要建立一個子執行緒,不同子執行緒負責接收不同使用者端的訊息 sub_thread = threading.Thread(target=handle_client_request, args=(service_client_socket, ip_port)) # 設定守護主執行緒 sub_thread.setDaemon(True) # 啟動子執行緒 sub_thread.start() # tcp伺服器端通訊端可以不需要關閉,因為伺服器端程式需要一直執行 # tcp_server_socket.close()
執行結果:
使用者端連線成功: ('172.16.47.209', 51528)
使用者端連線成功: ('172.16.47.209', 51714)
hello1 ('172.16.47.209', 51528)
hello2 ('172.16.47.209', 51714)
當建立一個TCP socket物件的時候會有一個傳送緩衝區和一個接收緩衝區,這個傳送和接收緩衝區指的就是記憶體中的一片空間。
send是不是直接把資料發給伺服器端?
不是,要想發資料,必須得通過網路卡傳送資料,應用程式是無法直接通過網路卡傳送資料的,它需要呼叫作業系統介面,也就是說,應用程式把傳送的資料先寫入到傳送緩衝區(記憶體中的一片空間),再由作業系統控制網路卡把傳送緩衝區的資料傳送給伺服器端網路卡 。
recv是不是直接從使用者端接收資料?
不是,應用軟體是無法直接通過網路卡接收資料的,它需要呼叫作業系統介面,由作業系統通過網路卡接收資料,把接收的資料寫入到接收緩衝區(記憶體中的一片空間),應用程式再從接收快取區獲取使用者端傳送的資料。
說明:
到此這篇關於Python網路程式設計(二)編寫TCP協定程式的文章就介紹到這了,更多相關Python TCP協定程式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45