zoukankan      html  css  js  c++  java
  • Python 使用socket实现ftp 客服端

    之前先了解ftp协议,然后解释代码
    1. 连接到ftp服务器,得到一个socket(这是一个连接到ftp命令端口socket)
    2. 发送必要request
    3. 第一步 Connect到服务器后,ftp_socket.recv(1024) 到服务器的欢迎消息(1 中的socket),不要问为什么,ftp协议规定的,应该是。*注意的是,后面ftp_socket每一次的请求后,都要recv一次,不管你是否全部接受到了都要recv一次,不然可能后面接受不到一些消息。个人觉着这可能是ftp协议的规定:每一次request,都会给client一个response。如果 client没有接受这个response,那么下次的request不会被服务器接受,所以client的recv就会卡住!
    4. 第二步就像代码中 直到 #LIST 都是用的命令端口。 而使用数据端口时,就是用命令端口  ftp_socket.send("PASV ")
          new_port = ftp_socket.recv(1024)     使用命令 PASV 请求一个动态的数据端口。
    5. 解释 我理解的动态数据端口: 即你每一次请求到一个数据端口后,你只能使用一次。比如:[ INFO] 2014-11-29 22:25:44,682 [admin] [127.0.0.1] SENT: 227 Entering Passive Mode (127,0,0,1,204,82)    这是ftp服务器端发送的请求(apache ftpserver),明显括号中是你的ip(我的是本机),然后两个数字。通过查询,你要请求的数据端口:(a,b,c,d,x,y)  new_port  = x*250+y
    6. 剩下的部分就很简单了。在代码中再有点解释(后面附server端log)
    7. 最后还应该用发送一个quit命令,告诉server 我的请求完毕了。这里忘了。
    8. 一点补充:看到server端log可以发现,服务器每一次的SEND  我们都应该recv一次

    #download a folder's files 
    import socket
    class ParseUrl():
        """docstring for ParseUrl"""
        def __init__(self, url):
            self.url = url
            self.method = ""
            self.host = ""
            self.port =""
        def get_method(self):
            method_url = self.url

            self.method = method_url.split(":")[0]

            print "Request Method:",self.method
            return self.method
        def get_host(self):
            temp_pos = self.url.find("://")
            temp_url = self.url[temp_pos+3:]
            
            self.host = temp_url[:temp_url.find(":")]

            print "Request Host:",self.host

            return self.host
        def get_port(self):

            tem_url = self.url.split(":")[2]

          
            if tem_url.find("/"):
                tem_url = tem_url[:tem_url.find("/")]

            print "Request Port:",tem_url  
            self.port = tem_url
            return self.port 
        def parse(self):
            temp_methd = self.get_method()
            temp_host = self.get_host()
            temp_port = self.get_port()
            return temp_methd,temp_host,temp_port


    def main():

        #ftp url
        request_url = "ftp://localhost:2121/"

        parse_url = ParseUrl(request_url)

        method,host,port = parse_url.parse()

        print "method,host,port",method,host,port
        #get connection to ftp server
        ftp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        ftp_socket.connect((host,int(port)))

        user = "admin "
        password = "admin "

        print ftp_socket.recv(1024)  #这个地方是用来接收欢迎消息

        ftp_socket.send("USER "+user)

        print ftp_socket.recv(1024)

        ftp_socket.send("PASS "+password)

        print ftp_socket.recv(1024)

        ftp_socket.send("CWD ")

        print ftp_socket.recv(1024)

        ftp_socket.send("TYPE ASCII ")

        print ftp_socket.recv(1024)
        
       

        ftp_socket.send("SIZE my.txt ")
        temp_size = ftp_socket.recv(1024)
        file_size = int(temp_size.split(" ")[1])

        print file_size

    #LIST 
        ftp_socket.send("PASV ")
        new_port = ftp_socket.recv(1024)
        print new_port
        before_port = ""
        temp_port =""

        if new_port.startswith("227"):
            temp_port = new_port.split(",")[5]
            before_port = new_port.split(",")[4]
            temp_port = temp_port.replace(") ","")
        #get the server's new port   
        new_request_port = int(before_port)*256+int(temp_port)
        # connect to the server's new port
        ftp_data_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        ftp_data_socket.connect((host,new_request_port))
        ftp_socket.send("LIST ")
        
        print ftp_data_socket.recv(1024).decode("utf-8")
        
        ftp_socket.recv(1024)


    #RETR
        ftp_socket.send("PASV ")
        new_port = ftp_socket.recv(1024)
        print new_port
        before_port = ""
        temp_port =""

        if new_port.startswith("227"):
            temp_port = new_port.split(",")[5]
            before_port = new_port.split(",")[4]
            temp_port = temp_port.replace(") ","")
        #get the server's new port   
        new_request_port = int(before_port)*256+int(temp_port)
        # connect to the server's new port
        ftp_data_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        ftp_data_socket.connect((host,new_request_port))

        ftp_socket.send("RETR my.txt ")

        file_content = ftp_data_socket.recv(file_size)
        
        print file_content

        download_file = open("my.txt","wb")
        download_file.write(file_content)
        download_file.close()
        #print  create_data_connection(ftp_socket,"LIST","",host)
    if __name__ == '__main__':
        main()





    SERVEER LOG:
    [ INFO] 2014-11-29 22:47:55,513 [] [127.0.0.1] CREATED
    [ INFO] 2014-11-29 22:47:55,514 [] [127.0.0.1] OPENED
    [ INFO] 2014-11-29 22:47:55,515 [] [127.0.0.1] SENT: 220 Service ready for new user.

    [ INFO] 2014-11-29 22:47:55,516 [] [127.0.0.1] RECEIVED: USER admin
    [ INFO] 2014-11-29 22:47:55,517 [admin] [127.0.0.1] SENT: 331 User name okay, need password for admin.

    [ INFO] 2014-11-29 22:47:55,519 [admin] [127.0.0.1] RECEIVED: PASS *****
    [ INFO] 2014-11-29 22:47:55,569 [admin] [127.0.0.1] Login success - admin
    [ INFO] 2014-11-29 22:47:55,569 [admin] [127.0.0.1] SENT: 230 User logged in, proceed.

    [ INFO] 2014-11-29 22:47:55,571 [admin] [127.0.0.1] RECEIVED: CWD 
    [ INFO] 2014-11-29 22:47:55,571 [admin] [127.0.0.1] SENT: 250 Directory changed to /

    [ INFO] 2014-11-29 22:47:55,572 [admin] [127.0.0.1] RECEIVED: TYPE ASCII 
    [ INFO] 2014-11-29 22:47:55,573 [admin] [127.0.0.1] SENT: 200 Command TYPE okay.

    [ INFO] 2014-11-29 22:47:55,574 [admin] [127.0.0.1] RECEIVED: SIZE my.txt
    [ INFO] 2014-11-29 22:47:55,574 [admin] [127.0.0.1] SENT: 213 4813

    [ INFO] 2014-11-29 22:47:55,575 [admin] [127.0.0.1] RECEIVED: PASV 
    [ INFO] 2014-11-29 22:47:55,576 [admin] [127.0.0.1] SENT: 227 Entering Passive Mode (127,0,0,1,213,199)

    [ INFO] 2014-11-29 22:47:55,579 [admin] [127.0.0.1] RECEIVED: LIST 
    [ WARN] 2014-11-29 22:47:55,610 [admin] [127.0.0.1] Releasing unreserved passive port: 54727
    [ INFO] 2014-11-29 22:47:55,610 [admin] [127.0.0.1] SENT: 150 File status okay; about to open data connection.

    [ INFO] 2014-11-29 22:47:55,610 [admin] [127.0.0.1] SENT: 226 Closing data connection.

    [ INFO] 2014-11-29 22:47:55,614 [admin] [127.0.0.1] RECEIVED: PASV 
    [ INFO] 2014-11-29 22:47:55,616 [admin] [127.0.0.1] SENT: 227 Entering Passive Mode (127,0,0,1,213,201)

    [ INFO] 2014-11-29 22:47:55,619 [admin] [127.0.0.1] RECEIVED: RETR my.txt
    [ INFO] 2014-11-29 22:47:55,621 [admin] [127.0.0.1] File downloaded /my.txt
    [ WARN] 2014-11-29 22:47:55,622 [admin] [127.0.0.1] Releasing unreserved passive port: 54729
    [ INFO] 2014-11-29 22:47:55,622 [admin] [127.0.0.1] SENT: 150 File status okay; about to open data connection.

    [ INFO] 2014-11-29 22:47:55,622 [admin] [127.0.0.1] SENT: 226 Transfer complete.
  • 相关阅读:
    【python】变量定义及全局局部变量
    【python】重要的内置函数
    【python】迭代器iterator
    Java序列化与反序列化
    java中的IO操作总结
    Java中List Set Map 是否有序等总结
    java.lang.Class.getDeclaredMethod()方法详解
    一个servlet处理多个请求(使用Method的反射机制)
    java类的访问权限
    java中的基本数据类型存放位置
  • 原文地址:https://www.cnblogs.com/-Doraemon/p/4700068.html
Copyright © 2011-2022 走看看