python socke ftp功能實現 shell命令,上傳,下載

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章