1. 程式人生 > >python學習——day8(socket,socket server) Alex網址:http://www.cnblogs.com/alex3714/articles/5227251.html

python學習——day8(socket,socket server) Alex網址:http://www.cnblogs.com/alex3714/articles/5227251.html

except per 滿足 udp ets pytho name 永遠 oca

一、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 >>bABC‘

小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(babc)    
 6 m.updata(b123)
 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