zoukankan      html  css  js  c++  java
  • socket 网络编程【实现FTP文件上传和下载】

    有四个基本的具体服务器类:

    class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
        这使用Internet TCP协议,它在客户端和服务器之间提供连续的数据流。如果bind_and_activate为true,构造函数将自动尝试调用server_bind()和server_activate()。其他参数传递到BaseServer基类。

    class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)
      这使用数据报,其是可能在运输中不按顺序到达或丢失的信息的离散分组。参数与TCPServer相同。

    class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
    class socketserver.UnixDatagramServer(server_address, RequestHandlerClass, bind_and_activate=True)
        这些更常用的类与TCP和UDP类类似,但使用Unix域套接字;它们在非Unix平台上不可用。参数与TCPServer相同。

    示例:使用SocketServer网络服务框架实现FTP文件上传和下载功能

    服务端:

     1 # !/usr/bin/python
     2 # -*- coding:utf-8 -*-
     3 '''
     4 _author_=Captain
     5 '''
     6 import SocketServer
     7 import os
     8 
     9 class Myserver(SocketServer.BaseRequestHandler):
    10     def handle(self):
    11         base_path="D:\temp"    #文件保存路径
    12         conn=self.request
    13         client_address=self.client_address
    14         print "客户端:"+str(client_address)+"connected..."
    15         conn.send("服务端已准备接收...")
    16         while True:
    17             pre_data1,pre_data2=conn.recv(1024).split('|')
    18             if pre_data1=='put':  #如果客户端是要上传文件
    19                 file_name,file_size=pre_data2.split('-')  #对客户端传递过来的文件名和文件大小两个值分割开
    20                 recv_size=0
    21                 file_dir=os.path.join(base_path,file_name)   #生成文件保存的路径
    22                 with open(file_dir,'wb') as f:
    23                     Flag = True
    24                     while Flag:
    25                         if int(file_size)>recv_size:
    26                             data = conn.recv(1024)
    27                             recv_size += len(data)
    28                             f.write(data)
    29                         else:
    30                             recv_size = 0
    31                             Flag = False
    32                             conn.send("upload successed")
    33 
    34             elif pre_data1 == 'get':   #如果客户端是要下载文件
    35                 file_size = os.stat(pre_data2).st_size
    36                 file_path,file_name = os.path.split(pre_data2)
    37                 conn.send(file_name + '|' + str(file_size))  #将文件名和计算出的文件大小发给客户端
    38                 send_size = 0
    39                 with open(pre_data2, 'rb') as f:
    40                     Flag = True
    41                     while Flag:
    42                         if send_size + 1024 > file_size:   #如果文件大小不是1024的倍数,即最后的数据
    43                             data = f.read(file_size - send_size)
    44                             Flag = False
    45                         else:
    46                             data = f.read(1024)
    47                             send_size += 1024
    48                         conn.send(data)
    49 
    50 
    51 if __name__ == '__main__':
    52     instance = SocketServer.ThreadingTCPServer(('127.0.0.1',8866), Myserver)  #使用异步多进程
    53     instance.serve_forever()
    View Code

    客户端:

     1 # !/usr/bin/python
     2 # -*- coding:utf-8 -*-
     3 '''
     4 _author_=Captain
     5 '''
     6 import socket
     7 import sys
     8 import os
     9 
    10 ip_port=('127.0.0.1',8866)
    11 sk=socket.socket()
    12 sk.connect(ip_port)
    13 print sk.recv(1024)   #接收服务端提示建立连接的消息
    14 while True:
    15     cmd,file_dir = raw_input('path:').split()  #对输入的命令进行分割,如:put c:xx11.txt
    16     if cmd=='put':
    17         file_path, file_name = os.path.split(file_dir)
    18         file_size=os.stat(file_dir).st_size    #计算文件大小
    19         sk.send(cmd + '|' + file_name + '-' + str(file_size))
    20         send_size = 0
    21         with open(file_dir,'rb') as f:
    22             Flag = True
    23             while Flag:
    24                 if send_size + 1024 > file_size:
    25                     data = f.read(file_size - send_size)
    26                     Flag = False
    27                 else:
    28                     data = f.read(1024)
    29                     send_size += 1024
    30                 sk.send(data)
    31             print sk.recv(1024)  # 接收服务端返回文件上传成功的消息
    32 
    33     elif cmd=='get':
    34         sk.send(cmd + '|' + file_dir)   #把要下载服务端某个文件的具体路径发送到服务端
    35         file_name,file_size=sk.recv(1024).split('|')   #接收服务端返回的文件名和文件大小
    36         file_dir = os.path.join(os.getcwd(), file_name)
    37         recv_size = 0
    38         with open(file_dir, 'wb') as f:
    39             Flag = True
    40             while Flag:
    41                 if int(file_size) > recv_size:
    42                     data = sk.recv(1024)
    43                     recv_size += len(data)
    44                     f.write(data)
    45                 else:
    46                     recv_size = 0
    47                     Flag = False
    48                     print 'download successed,文件已保存到 %s' % file_dir
    49     else:
    50         print "请输入put或get命令,确认是上传还是下载文件"
    51 
    52 sk.close()
    View Code
    我们的征途是星辰大海
  • 相关阅读:
    LeetCode 81 Search in Rotated Sorted Array II(循环有序数组中的查找问题)
    LeetCode 80 Remove Duplicates from Sorted Array II(移除数组中出现两次以上的元素)
    LeetCode 79 Word Search(单词查找)
    LeetCode 78 Subsets (所有子集)
    LeetCode 77 Combinations(排列组合)
    LeetCode 50 Pow(x, n) (实现幂运算)
    LeetCode 49 Group Anagrams(字符串分组)
    LeetCode 48 Rotate Image(2D图像旋转问题)
    LeetCode 47 Permutations II(全排列)
    LeetCode 46 Permutations(全排列问题)
  • 原文地址:https://www.cnblogs.com/honey-badger/p/8414641.html
Copyright © 2011-2022 走看看