解析**的思路:
首先,先將伺服器和客戶端的建立連線,連線成功後,客戶端要先將自己的請求傳送至server,因為ftp的get是處理檔案的,所以採用cmd.startwith('get')作為判斷條件,這個時候必須收到server的應答,server_response,表示server已經準備可以接受資料了,這個時候client就將資料傳送過去,然後server接收,注意只要server發或者收,同樣的client也必須收或者發,不然由於採用accept是阻塞型的,只有收到recv才會繼續進行下去,這與ftp協議是一致的.
#client
import socket
import hashlib
client = socket.socket()
client.connect(('localhost',9999))
while true:
cmd = input(">>: ").strip()
if len(cmd) == 0:continue
if cmd.startswith("get"):
client.send(cmd.encode())
server_response = client.recv(1024)
print("server response: ",server_response)
client.send(b"ready to recv file")
file_total_size = int(server_response.decode())
received_size = 0
filename = cmd.split()[1]
f = open(filename + ".new","wb")
m = hashlib.md5()
while received_size < file_total_size:
if file_total_size - received_size > 1024:
size = 1024
else:
size = file_total_size -received_size
print("last received:",size)
data = client.recv(size)
received_size += len(data)
m.update(data)
f.write(data)
else:
new_file_md5 = m.hexdigest()
print("file recv done",received_size,file_total_size)
f.close()
server_file_md5 = client.recv(1024)
print("server file md5: ",server_file_md5)
print("client file md5: ",new_file_md5)
client.close()
#server
import socket,os
import hashlib
server = socket.socket()
server.bind(('0.0.0.0',9999))
server.listen(5)
print("等待連線....")
while true:
conn,addr = server.accept()
print("連線成功....")
while true:
print("等待指令")
data = conn.recv(1024)
if not data:
print("客戶端已斷開")
break
cmd,filename = data.decode().split()
print(filename)
if os.path.isfile(filename):
f = open(filename,"rb")
m = hashlib.md5()
file_size = os.stat(filename).st_size
conn.send( str(file_size).encode() )
conn.recv(1024)#wait for ask
for line in f:
m.update(line)
conn.send(line)
print("file md5",m.hexdigest())
f.close()
conn.send(m.hexdigest().encode())
print("檔案傳送完畢....")
server.close()
其中
ftp server讀取檔名,檢測檔案是否存在os.path.isfile(filename)
開啟檔案open()檢測檔案大小 received_size和file_total_size比較防止粘包,
傳送檔案大小給客戶端,等客戶端確認大小,然後開始邊讀邊發資料傳送md5
客戶端的md5與伺服器端的md5對比,相同即檔案傳輸過程沒有改變
md5的使用過程
import hashlib
md5=hashlib.md5()
md5.update(r'str')
md5.hexdigest()
要是send的話需要將檔案的內容decode,encode預設是utf-8
Python socket模擬HTTP請求
最近在做乙個對時間要求比較高的掃瞄器,需要封裝一下socket模擬http發包的一些常用函式。簡單的說,就是重寫一下requests中的get post方法。今天在寫的時候,遇到一枚很奇怪的問題,對同乙個url,post請求能正常返回資訊,而一旦切到get,socket time out。偽 如下 ...
Python Socket 程式設計
client import socket,sys if name main 處理引數 argv sys.argv if len argv 3 or len argv 2 and argv 1 print useage argv 0 sys.exit 0 host argv 1 server ip位址...
python socket程式設計
python 編寫server的步驟 1.第一步是建立socket物件。呼叫socket建構函式。如 socket socket.socket family,type family引數代表位址家族,可為af inet或af unix。af inet家族包括internet位址,af unix家族用於...