python socke ftp功能實現 shell命令,上傳,下載
網上教程多,但是都不全,只有下載代碼
本人練習,附加了註釋,幫助新人練習
一定要吃透socket來回仍包的原理
編寫時,要2個腳本一起開工,才能理解包來回仍的邏輯
功能實現
1,執行shell命令
2,執行上傳
3,執行下載
服務端
#coding=UTF-8
import socket #導入socket類
import SocketServer,commands,os
#定義返回函數
def message( code ):
print "------",code
def sendmessage(obj,code):
obj.request.send(str( len(code) ))
obj.request.send(code)
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
print '已建立連接:', self.client_address
while True:
#接收消息
cmd = self.request.recv(1024)
#如果消息無,結束連接
if not cmd:
print 'Lost connection with', self.client_address
break
#執行cmd命令
#cmd_result = commands.getstatusoutput(cmd)
#打印接收的消息
print cmd
if ( cmd == "wqtest" ):
cmd_result="login pass"
self.request.send(str( len(cmd_result) ))
self.request.send(cmd_result)
#等待接收命令shell,put,get
while True:
cmd = self.request.recv(1024)
if not cmd:
print 'Lost connection with', self.client_address
break
print cmd
user_command=cmd.split()
if ( user_command[0] == "shell" ):
print "執行cmd命令"
sendmessage(self,"執行cmd命令")
cmd_result = commands.getstatusoutput(user_command[1])
print "parameter2:",user_command[1]
print "result len:",len(cmd_result)
print "result 1:",cmd_result[0]
print "result 2:",cmd_result[1]
sendmessage(self,cmd_result[1])
elif ( user_command[0] == "input" ):
print "執行上傳命令"
sendmessage(self,"執行上傳命令")
#獲取大小
feedback = self.request.recv(100)
if ( feedback.startswith("ready") ):
#接收大小
file_size = int(feedback.split()[-1])
#反饋服務器,已經準備好
self.request.send("recv_ready")
#循環接收
recv_size = 0
#本地創建文件s
file_name = user_command[1]
f = file(os.path.basename(file_name),'wb')
print "--->",file_name
while not file_size == recv_size:
if file_size - recv_size > 1024:
data = self.request.recv(1024)
recv_size += len(data)
else:
data = self.request.recv( file_size - recv_size )
recv_size += ( file_size - recv_size )
#接收就寫入
f.write(data)
print file_size,recv_size
print "get %s done" % file_name
elif ( user_command[0] == "get" ):
print "執行下載命令"
#sendmessage(self,"執行下載命令")
#獲取文件名
file_name = user_command[1]
print "client wants to download file:", user_command[1]
#判斷文件是否存在
if ( os.path.isfile( user_command[1] ) ):
print "pass"
file_size = os.path.getsize(user_command[1])
#發送文件大小
res = "ready %s" % file_size
else:
#發送文件大小
print "faile"
res = "file doesn't exist"
print '---->',res
sendmessage(self,res)
#等待回話,結果,不直接發送,是爲了避免粘包
print feedback
feedback = self.request.recv(100)
if ( feedback == "recv_ready"):
#讀取文件
f = file(user_command[1],'rb')
#循環發送
send_size = 0
while not file_size == send_size:
if file_size - send_size > 1024:
data = f.read(1024)
send_size += 1024
else:
data = f.read(file_size - send_size)
send_size += ( file_size - send_size )
print file_size,send_size
#每次都發消息
self.request.send(data)
else:
print '---send file:%s done----' % user_command[1]
f.close()
else:
cmd_result="login false"
#反迴響應值長度和結果
message(cmd_result)
sendmessage(self,cmd_result)
if __name__ == "__main__":
HOST,PORT="",9999
server = SocketServer.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
server.serve_forever()
客戶端
#coding=UTF-8
import socket,os
HOST = '172.0.71.48'
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
#user_input = raw_input("What do you wangt tu buy?").strip()
#結果值拼串處理
def recv_all(obj,msg_length):
raw_result = ''
while True:
if msg_length <= 4096:
data = obj.recv(msg_length)
print '======',data
raw_result += data
break
else:
data=obj.recv(4096)
raw_result += data
msg_length -=4096
return raw_result
def recv_result(obj):
#接收響應值大小size
res_size = obj.recv(1024)
print 'size:',res_size
#接收響應值的結果
result = recv_all(obj,int(res_size))
print 'result:',result
return result
while True:
#請輸入密碼
user_input = raw_input("請輸入口令?").strip()
#如果密碼爲空
if( len(user_input)) == 0:
continue
else:
s.send(user_input)
#等待接收響應值
result = recv_result(s)
if ( result == "login pass" ):
while True:
user_input = raw_input("請輸入命令?").strip()
#分割字符串
user_command=user_input.split()
print "數組長度:",len(user_command)
#如果長度爲2才進行指令發送
if ( len(user_command) == 2 ):
if ( user_command[0] == "get" ):
print "clinet get"
s.send(user_input)
#等待接收響應值
#recv_result(s)
#等待接收響應值,確認文件是否存在
feedback = recv_result(s)
print "----->",feedback
if ( feedback.startswith("ready") ):
#接收大小
file_size = int(feedback.split()[-1])
#反饋服務器,已經準備好
s.send("recv_ready")
#循環接收
recv_size = 0
#本地創建文件
file_name = user_command[1]
f = file(os.path.basename(file_name),'wb')
print "--->",file_name
while not file_size == recv_size:
if file_size - recv_size > 1024:
data = s.recv(1024)
recv_size += len(data)
else:
data = s.recv( file_size - recv_size )
recv_size += ( file_size - recv_size )
#接收就寫入
f.write(data)
print file_size,recv_size
print "get %s done" % file_name
else:
#打印文件不存在
print feedback
s.send("recv_faile")
elif ( user_command[0] == "input" ):
print "clinet input"
s.send(user_input)
#等待接收響應值
recv_result(s)
#判斷文件是否存在
if ( os.path.isfile( user_command[1] ) ):
print "pass"
file_size = os.path.getsize(user_command[1])
#發送文件大小
res = "ready %s" % file_size
print '---->',res
#發送大小
s.send(res)
feedback = s.recv(100)
if ( feedback == "recv_ready"):
#讀取文件
f = file(user_command[1],'rb')
#循環發送
send_size = 0
while not file_size == send_size:
if file_size - send_size > 1024:
data = f.read(1024)
send_size += 1024
else:
data = f.read(file_size - send_size)
send_size += ( file_size - send_size )
print file_size,send_size
#每次都發消息
s.send(data)
else:
print '---send file:%s done----' % user_command[1]
f.close()
else:
#發送文件大小
print "faile"
res = "file doesn't exist"
print '---->',res
s.send(res)
elif ( user_command[0] == "shell" ):
print "clinet shell"
s.send(user_input)
#等待接收響應值
recv_result(s)
#等待接收響應值
recv_result(s)
else:
print "please input the commands like get *,input *,shell *"
else:
print "wrong in your commands,the parameter must equal two !"
s.close() #關閉socket