66.並行(parallel)和並發(concurrency)?
並行:同一時刻多個任務同時在運行。
並發:在同一時間間隔內多個任務都在運行,但是並不會在同一時刻同時運行,存在交替執行的情況。
實現並行的庫有:multiprocessing
實現並發的庫有:threading
程序需要執行較多的讀寫、請求和回復任務的需要大量的 IO 操作,IO密集型操作使用並發更好。
CPU運算量大的程序程序,使用並行會更好。
IO密集型和CPU密集型區別?
IO密集型:系統運作,大部分的狀況是CPU在等 I/O (硬盤/內存)的讀/寫。
CPU密集型:大部份時間用來做計算、邏輯判斷等 CPU動作的程序稱之CPU密集型。
67.使用udp發送/接收數據步驟:
1.創建客戶端套接字
2.發送/接收數據
3.關閉套接字
import socket
def main():
# 1、創建udp套接字
# socket.AF_INET 表示IPv4協議 AF_INET6 表示IPv6協議
# socket.SOCK_DGRAM 數據報套接字,只要用於udp協議
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2、准備接收方的地址
# 元組類型 ip是字符串類型 端口號是整型
dest_addr = ('192.168.113.111', 8888)
# 要發送的數據
send_data = "我是要發送的數據"
# 3、發送數據
udp_socket.sendto(send_data.encode("utf-8"), dest_addr)
# 4、等待接收方發送的數據 如果沒有收到數據則會阻塞等待,直到收到數據
# 接收到的數據是一個元組 (接收到的數據, 發送方的ip和端口)
# 1024 表示本次接收的最大字節數
recv_data, addr = udp_socket.recvfrom(1024)
# 5、關閉套接字
udp_socket.close()
if __name__ == '__main__': 22. main() 編碼的轉換
str -->bytes: encode編碼
bytes--> str: decode()解碼
68.UDP綁定端口號:
1.創建socket套接字
2.綁定端口號
3.接收/發送數據
4.關閉套接字
import socket
def main():
# 1、創建udp套接字
# socket.AF_INET 表示IPv4協議 AF_INET6 表示IPv6協議
# socket.SOCK_DGRAM 數據報套接字,只要用於udp協議
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2、綁定端口
# 元組類型 ip一般不寫 表示本機的任何的一個ip
local_addr = ('', 7777)
udp_socket.bind(local_addr)
# 3、准備接收方的地址
# 元組類型 ip是字符串類型 端口號是整型
dest_addr = ('192.168.113.111', 8888)
# 要發送的數據
send_data = "我是要發送的數據"
# 4、發送數據
udp_socket.sendto(send_data.encode("utf-8"), dest_addr)
# 5、等待接收方發送的數據 如果沒有收到數據則會阻塞等待,直到收到數據
# 接收到的數據是一個元組 (接收到的數據, 發送方的ip和端口)
# 1024 表示本次接收的最大字節數
recv_data, addr = udp_socket.recvfrom(1024)
# 6、關閉套接字
udp_socket.close()
if __name__ == '__main__':
main() 注意點:綁定端口要在發送數據之前進行綁定。
69.TCP客戶端的創建流程:
1.創建TCP的socket套接字
2.連接服務器
3.發送數據給服務器端
4.接收服務器端發送來的消息
5.關閉套接字
import socket
def main():
# 1、創建客戶端的socket
# socket.AF_INET 表示IPv4協議 AF_INET6 表示IPv6協議
# socket.SOCK_STREAM 流式套接字,只要用於TCP 協議
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、構建目標地址
server_ip = input("請輸入服務器端的IP地址:")
server_port = int(input("請輸入服務器端的端口號:"))
# 3、連接服務器
# 參數:元組類型 ip 是字符串類型 端口號是整型
client_socket.connect((server_ip, server_port))
# 要發送給服務器端的數據
send_data = "我是要發送給服務器端的數據"
# 4、發送數據
client_socket.send(send_data.encode("gbk"))
# 5、接收服務器端恢復的消息, 沒有消息會阻塞
# 1024表示接收的最大字節數
recv_date= client_socket.recv(1024)
print("接收到的數據是:", recv_date.decode('gbk'))
# 6、關閉套接字
client_socket.close()
if __name__ == '__main__':
main()
70.TCP服務器端的創建流程
1.創建TCP服務端的socket
2.bing綁定ip地址和端口號
3.listen使套接字變為被動套接字
4.accept取出一個客戶端連接,用於服務
5.recv/send接收和發送消息
6.關閉套接字
import socket
def main():
# 1、創建tcp服務端的socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、綁定
server_socket.bind(('', 8888))
# 3、listen使套接字變為被動套接字
server_socket.listen(128)
# 4、如果有新的客戶端來鏈接服務器,那么就產生一個新的套接字專門為這個客戶端服務
# client_socket用來為這個客戶端服務
# tcp_server_socket就可以省下來專門等待其他新客戶端的鏈接
client_socket, client_addr = server_socket.accept()
# 5、接收客戶端發來的消息
recv_data = client_socket.recv(1024)
print("接收到客戶端%s的數據:%s" % (str(client_addr), recv_data.decode('gbk')))
# 6、回復數據給客戶端
client_socket.send("收到消息".encode('gbk'))
# 7、關閉套接字
client_socket.close()
server_socket.close()
if __name__ == '__main__':
main()