python學習——day8(socket,socket server) Alex網址:http://www.cnblogs.com/alex3714/articles/5227251.html
一、socket
定義:
socket本質上就是在2臺網絡互通的電腦之間,架設一個通道,兩臺電腦通過這個通道來實現數據的互相傳遞。 我們知道網絡 通信 都 是基於 ip+port 方能定位到目標的具體機器上的具體服務,操作系統有0-65535個端口,每個端口都可以獨立對外提供服務,如果 把一個公司比做一臺電腦 ,那公司的總機號碼就相當於ip地址, 每個員工的分機號就相當於端口, 你想找公司某個人,必須 先打電話到總機,然後再轉分機 。
建立一個socket必須至少有2端, 一個服務端,一個客戶端, 服務端被動等待並接收請求,客戶端主動發起請求, 連接建立之後,雙方可以互發數據。
最簡單的服務器端和客戶端:
1 #服務器端 2 import socket 3 server=socket.socket(地址簇,套接字) #聲明 4 5 server.bind(("localhost",9999)) #確定監聽的端口 6 7 server.listen() #開始監聽 8 9 conn,addr=server.accpet() #在服務器端生成實例並賦值 10 print("new conn:",addr) 11 12 while True: #服務器端循環接收數據 13 14 data=conn.recv(1024) #接受數據,最多1K 15 print(data) #>>b‘abc‘ 16 17 conn.send(data.upper) #將數據改為大寫發回去
1 #客戶端 2 import socket 3 4 client=socket.socket() #實例化 5 6 client.connect("localhost",9999) #綁定IP和端口 7 8 client.send(b"abc") #轉為二進制發送 9 10 data=client.recv(1024) 11 12 print(data)13 14 >>b‘ABC‘
小Tips:
地址簇:
AF.INET(IPV4,默認)
AF.ZNET6(IPV6)
AF.UNTX(local)
套接字:
socket.
SOCK_STREAM #for tcp
socket.
SOCK_DGRAM #for udp
解決各種問題版(數據過大一次傳不完,粘包等):
1 #服務器端 2 import socket,os 3 server=socket.socket(地址簇,套接字) #聲明 4 5 server.bind(("localhost",9999)) #確定監聽的端口 6 7 server.listen() #開始監聽 8 9 conn,addr=server.accpet() #在服務器端生成實例並賦值 10 print("new conn:",addr) 11 12 while True: #服務器端循環接收數據 13 14 data=conn.recv(1024) #接受數據,最多1K 15 data=data.decode() #二進制轉成‘utf-8‘ 16 if no data : 17 print(‘客戶端已斷開‘) 18 break 19 print(‘執行指令:‘,data) 20 21 cmd_res=os.popen(data).read() #執行操作 22 23 conn.send(len(cmd_res).encode(‘utf-8‘)) #先發送數據的大小 24 25 time.sleep(0.5) #先睡0.5s 防止粘包(當然這很low),後面講NB的 26 27 conn.send(cmd_res.encode(‘utf-8‘)) #將數據發回去 28 29 server.close() #我好像前面都忘寫關閉了(anyway)
1 #客戶端 2 import socket 3 4 client=socket.socket() #實例化 5 6 client.connect("localhost",9999) #綁定IP和端口 7 8 while True: 9 cmd = input(">>:").strip() 10 11 client.send(cmd.encode(‘utf-8‘)) 12 13 cmd_res_size=(client.recv(1024)).decode() #要傳輸的文件的大小 14 received_size=0 #本地已有的文件大小(斷點續傳,請看FTP作業) 15 received_data=b‘‘ 16 print("命令結果大小",cmd_res_size) 17 while received_size<cmd_res_size: 18 data=client.recv(1024) 19 received_data+=data 20 received_size+=len(data) 21 else: 22 print("數據接收完畢") 23 print(received_data.decode()) 24 25 client.close()
ftp_server:(詳情看FTP作業)
1. 讀取文件名
2. 檢測文件是否存在
3. 打開文件
4. 檢測文件大小
5. 發送文件大小給客戶端
6. 等客戶端確認
7. 開始邊讀邊發數據
8. 發送md5
溫習下加密:
1 import hashlib 2 3 m=hashlib.md5 4 5 m.updata(b‘abc‘) 6 m.updata(b‘123‘) 7 8 #m.updata(b‘abc123‘) #兩者結果一毛一樣,so可以采用這種方式讀取文件計算md5值 9 10 print(m.hexdigest) #16進制
二、socket server
多線程滿足條件:
1.你必須自己創建一個請求處理類,並且這個類要繼承BaseRequestHandler,並且還有重寫父親類裏的handle()
2.你必須實例化TCPServer ,並且傳遞server ip 和 你上面創建的請求處理類 給這個TCPServer
3.server.handle_request() #只處理一個請求
4.server.serve_forever() #處理多個一個請求,永遠執行
1 import socketserver 2 3 class MyTCPHandler(socketserver.BaseRequestHandler): #條件1,自己創建一個類 4 def handle(self): #重寫父類中的handle() 5 while True: 6 try: 7 self.data = self.request.recv(1024).strip() 8 print("{} wrote:".format(self.client_address[0])) 9 print(self.data) 10 self.request.send(self.data.upper()) 11 except ConnectionResetError as e: 12 print("err",e) 13 break 14 if __name__ == "__main__": 15 HOST, PORT = "localhost", 9999 16 # Create the server, binding to localhost on port 9999 17 server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) #實例化ThreadingTCPServer,並傳遞(端口號+IP),和請求類名 18 server.serve_forever() #關閉
python學習——day8(socket,socket server) Alex網址:http://www.cnblogs.com/alex3714/articles/5227251.html