🌌 專注Golang,Python語言,云原生,人工智能領域得博主;
💜 過去經歷的意義在于引導你,而非定義你;
📢 歡迎點贊 👍 收藏 ?留言!

01-tcp客戶端程式開發
import socket
if __name__ == '__main__':
# 1. 創建 socket 物件(socket.socket(ip 型別, 協議))
# socket.AF_INET ipv4 socket.AF_INET6 ipv6
# socket.SOCK_STREAM tcp
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 固定的寫法
# 2. 和服務器建立連接(socket物件.connect((服務器 ip 地址, 埠號))) 型別是元組
client_socket.connect(('192.168.155.43', 8080))
print('連接建立成功......')
# 3. 發送資訊(socket物件.send(發送的資訊)) 型別 bytes
send_data = '你好服務器,我是客戶端 9527....'.encode() # 默認是 utf-8
client_socket.send(send_data)
# 4. 接收對法發的資訊(socket物件.recv(一次接收多少位元組的資料))
# 如果對方沒有發送資訊, recv 函式會在此阻塞等待
buf = client_socket.recv(4096)
try:
print(buf.decode())
except UnicodeDecodeError:
print(buf.decode('gbk'))
# 5. 關閉連接(socket物件.close())
client_socket.close()
02-tcp 服務端程式開發
import socket
if __name__ == '__main__':
# 1. 創建 socket 物件
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 系結 IP 和埠 bind((ip, 埠)) 元組型別
# server_socket.bind(('192.168.155.43', 9000))
server_socket.bind(('', 9000)) # 系結服務器中任意的一個網卡
# 3. 設定監聽, 引數,代表同時鏈接服務器的客戶端數, 鏈接成功之后,就不占用這個名額
server_socket.listen(128)
print('等待連接中......')
# 4. 阻塞等待客戶端的鏈接, 回傳一個元組 (新的socket, (客戶端的ip, 埠))
new_socket, ip_port = server_socket.accept()
print(f'客戶端 {ip_port} 連接了......')
# 5. 新的 socket 收資訊, 阻塞等待
buf = new_socket.recv(4096)
print('接收到的資訊為', buf.decode())
# 6. 新的 socket 發資訊
send_data = '資訊已收到, over....'.encode()
new_socket.send(send_data)
# 7. 關閉
new_socket.close()
server_socket.close()
03-設定埠復用
import socket
if __name__ == '__main__':
# 1. 創建 socket 物件
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 設定埠復用
# level 設定那個級別的 socket, socket.SOL_SOCKET 當前的 socket
# optname 設定什么內容(權限) socket.SO_REUSEADDR 埠復用
# value 設定為什么值, True
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 2. 系結 IP 和埠 bind((ip, 埠)) 元組型別
# server_socket.bind(('192.168.155.43', 9000))
server_socket.bind(('', 9000)) # 系結服務器中任意的一個網卡
# 3. 設定監聽, 引數,代表同時鏈接服務器的客戶端數, 鏈接成功之后,就不占用這個名額
server_socket.listen(128)
print('等待連接中......')
# 4. 阻塞等待客戶端的鏈接, 回傳一個元組 (新的socket, (客戶端的ip, 埠))
new_socket, ip_port = server_socket.accept()
print(f'客戶端 {ip_port} 連接了......')
# 5. 新的 socket 收資訊, 阻塞等待
buf = new_socket.recv(4096)
print('接收到的資訊為', buf.decode())
# 6. 新的 socket 發資訊
send_data = '資訊已收到, over....'.encode()
new_socket.send(send_data)
# 7. 關閉
new_socket.close()
server_socket.close()
04-判斷客戶端程式的斷開
import socket
if __name__ == '__main__':
# 1. 創建 socket 物件
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 設定埠復用
# level 設定那個級別的 socket, socket.SOL_SOCKET 當前的 socket
# optname 設定什么內容(權限) socket.SO_REUSEADDR 埠復用
# value 設定為什么值, True
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 2. 系結 IP 和埠 bind((ip, 埠)) 元組型別
# server_socket.bind(('192.168.155.43', 9000))
server_socket.bind(('', 9000)) # 系結服務器中任意的一個網卡
# 3. 設定監聽, 引數,代表同時鏈接服務器的客戶端數, 鏈接成功之后,就不占用這個名額
server_socket.listen(128)
print('等待連接中......')
# 4. 阻塞等待客戶端的鏈接, 回傳一個元組 (新的socket, (客戶端的ip, 埠))
new_socket, ip_port = server_socket.accept()
print(f'客戶端 {ip_port} 上線了......')
# 5. 新的 socket 收資訊, 阻塞等待
# 當對方的 socket close 之后, 自己的 socket 不再阻塞了, recv 接收的內容是 空字串, 長度為 0
buf = new_socket.recv(4096)
if buf:
print('接收到的資訊為', buf.decode())
# 6. 新的 socket 發資訊
send_data = '資訊已收到, over....'.encode()
new_socket.send(send_data)
else:
print(f'客戶端{ip_port} 下線了.....')
# 7. 關閉
new_socket.close()
server_socket.close()
05-多任務版本的服務器
import socket
import threading
def handle_client_request(n_socket, client_ip_port):
# 5. 新的 socket 收資訊, 阻塞等待
# 當對方的 socket close 之后, 自己的 socket 不再阻塞了, recv 接收的內容是 空字串, 長度為 0
while True:
buf = n_socket.recv(4096)
if buf:
print(f'接收到{client_ip_port}的資訊:', buf.decode())
# 6. 新的 socket 發資訊
send_data = '資訊已收到, over....'.encode()
n_socket.send(send_data)
else:
print(f'客戶端{client_ip_port} 下線了.....')
break
# 7. 關閉
n_socket.close()
if __name__ == '__main__':
# 1. 創建 socket 物件
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 2. 系結 IP 和埠 bind((ip, 埠)) 元組型別
server_socket.bind(('', 9000)) # 系結服務器中任意的一個網卡
# 3. 設定監聽, 引數,代表同時鏈接服務器的客戶端數, 鏈接成功之后,就不占用這個名額
server_socket.listen(128)
print('等待連接中......')
while True: # 回圈等待客戶端的鏈接
new_socket, ip_port = server_socket.accept()
print(f'客戶端 {ip_port} 上線了......')
# 創建執行緒,執行任務
sub_thread = threading.Thread(target=handle_client_request, args=(new_socket, ip_port))
# 啟動執行緒
sub_thread.start()
server_socket.close() # 關閉監聽的 socket
06-gevent 的使用
# 1. 匯入 gevent
import gevent
def sing(singer, song):
for i in range(5):
print(f'{singer} 正在唱歌 {song}......')
# gevent 遇到 I/O 耗時阻塞操作,會切換協程
gevent.sleep(0.1) # 切換協程
def dance(dancer, name):
for i in range(8):
print(f"{dancer} 正在跳舞{name}------")
gevent.sleep(0.1)
if __name__ == '__main__':
# 2. 創建協程物件
g1 = gevent.spawn(sing, '學友', '冰雨')
g2 = gevent.spawn(dance, '小春', 'xxxxx')
# 3. 阻塞等待協程物件 join, gevent 遇到 I/O 耗時阻塞操作,會切換協程
g1.join()
g2.join()
07-補丁
# 1. 匯入 gevent
import gevent
import time
from gevent import monkey
monkey.patch_all() # 使用 gevent 中模塊替換系統中的模塊
def sing(singer, song):
for i in range(5):
print(f'{singer} 正在唱歌 {song}......')
# gevent 遇到 I/O 耗時阻塞操作,會切換協程
# gevent.sleep(0.1) # 切換協程
time.sleep(0.1)
def dance(dancer, name):
for i in range(8):
print(f"{dancer} 正在跳舞{name}------")
# gevent.sleep(0.1)
time.sleep(0.1)
if __name__ == '__main__':
# 2. 創建協程物件
g1 = gevent.spawn(sing, '學友', '冰雨')
g2 = gevent.spawn(dance, '小春', 'xxxxx')
# 3. 阻塞等待協程物件 join, gevent 遇到 I/O 耗時阻塞操作,會切換協程
g1.join()
g2.join()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/389054.html
標籤:AI
