一、多線程
每個程序在運行的時候(進程)系統都會為這個進程創建一個線程,這個線程我們叫主線程。
程序員自己創建的線程叫子線程
多個任務在一個線程中是按順序一個一個執行的(線程的串行)
多個線程的任務同時執行
import time
import datetime
from random import randint
import threading
def download(file):
print(file,threading.current_thread())
print(datetime.datetime.now(),'開始下載:%s' % file)
# sleep(時間): 會將當前線程阻塞指定的時間(停指定的時間然后再往后執行)
# 時間單位:秒
time1 = randint(5, 10)
time.sleep(time1)
print(datetime.datetime.now(),'下載%s結束'%file,'總共耗時:%d' % time1)
"""
python通過threading標準庫來支持多線程
"""
if __name__ == '__main__':
# download('肖生克的救贖')
# current_thread()獲取當前線程
print(threading.current_thread())
# 1.創建一個線程對象
"""
Thread(target=, args=)
target: 需要傳一個需要在子線程中執行的函數(類型是function的變量)
agrs: 在子線程中調用target對應的函數的時候,該傳什么參數。類型是元祖
"""
t1 = threading.Thread(target=download, args=('阿甘正傳',))
t2 = threading.Thread(target=download, args=('肖生克的救贖',))
# 2.讓子線程去執行任務
t1.start()
t2.start()
print('===========')
二、創建線程
from threading import Thread,current_thread
import time
from datetime import datetime
"""
創建線程方式1:
直接通過Thread類創建對象,將需要在子線程中執行的函數作為target參數傳進去
創建線程方式2:
- a.寫一個自己的類去繼承Thread類
- b.重寫當前類的run方法,run中的任務就是在子線程中執行的任務
- c.創建當前類的對象, 就是線程對象。然后調用start去執行線程中任務
"""
1.創建線程類
class DownLoadThread(Thread):
"""下載線程類"""
def __init__(self, file):
super().__init__()
self.file = file
def run(self):
# 注意:如果需要給run方法中傳數據,通過當前類的屬性來傳
print('%s開始下載:' % self.file, datetime.now())
time.sleep(5)
print('%s下載結束:' % self.file, datetime.now())
2.創建線程對象
t1 = DownLoadThread('阿甘正傳')
t2 = DownLoadThread('沉默的羔羊')
3.通過start去執行run中的任務
"""
注意: 如果直接調用run方法,run方法中的任務不會在當前的子線程中執行
# t1.run()
t1.start()
t2.start()
三、多線程聊天的服務器
"""__author__ = 余婷"""
import socket
from threading import Thread
class ConversationThread(Thread):
def __init__(self, conversation: socket.socket, addr):
super().__init__()
self.conversation = conversation
self.addr = addr
def run(self):
# 保持通話
while True:
# 接收消息
message_re = self.conversation.recv(1024).decode('utf-8')
print(self.addr[0], ':', message_re)
# 發送消息
message = 'hi %s,你好!' % self.addr[0]
self.conversation.send(message.encode('utf-8'))
def creat_server():
server = socket.socket()
server.bind(('10.7.156.97', 8081))
server.listen(512)
# 讓服務器一直運行
while True:
# 會阻塞線程
conversation, addr = server.accept()
# 創建處理這個請求對應的子線程
t = ConversationThread(conversation, addr)
t.start()
if __name__ == '__main__':
creat_server()
四、客戶端
"""__author__ = 余婷"""
import socket
client = socket.socket()
client.connect(('10.7.156.97', 8081))
while True:
message = input('>>>')
client.send(message.encode('utf-8'))
message_re = client.recv(1024).decode('utf-8')
print(message_re)
五、發送服務器
"""__author__ = 余婷"""
import socket
server = socket.socket()
server.bind(('10.7.156.97', 8082))
server.listen(512)
while True:
conversation, addr = server.accept()
message_re = conversation.recv(1024).decode('utf-8')
if message_re == '1':
# 發送圖片
print('發送圖片')
with open('./files/luffy.jpeg', 'br') as f:
content = f.read()
conversation.send(content) # 發送圖片信息
conversation.close()
elif message_re == '2':
message = input('>>>')
conversation.send(message.encode('utf-8'))
conversation.close()
六、接收圖片文字客戶端
"""__author__ = 余婷"""
import socket
number = 0
page = """
===========================
1. 需要圖片
2. 需要文字
3. 通知結束
==========================="""
while True:
client = socket.socket()
client.connect(('10.7.156.97', 8082))
print(page)
value = input('請選擇(1-3):')
# 發送數據
client.send(value.encode('utf-8'))
# 接收服務器返回的數據
if value == '1':
data = bytes()
message_re = client.recv(1024)
while message_re:
print('接收到圖片')
data += message_re
message_re = client.recv(1024)
# 關閉連接
client.close()
number += 1
with open('./new%d.jpeg'%number, 'wb') as f:
f.write(data)
elif value == '2':
message_re = client.recv(1024)
print(message_re.decode('utf-8'))
# client.close()