python socke ftp功能实现 shell命令,上传,下载

本文介绍了一种使用Python Socket实现FTP功能的方法,包括通过shell命令交互、文件上传和下载等功能。该实现帮助初学者理解socket通信原理,并提供了一个完整的客户端和服务端代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值