python3 用socket编写ftp

基本思想:本次主要实现使用socket来实现ftp功能,最简单的文件上传和下载功能,和简单的shell命令模式,即客户端与服务器端建立连接后,有客户端发送命令,服务器端返回命令结果,下面直接上代码:

【注】一开始想写成面向对象的编程格式(类),但是由于本人技术小白,无法将socket自身的实例化带入到具体的函数中,相互关联,并且浪费了很多时间和尝试,最终还是放弃,但是以后也会继续向这方面努力的。

server端:

import socket
import os
print ("Waitting connected......")
HostPort = ('127.0.0.1',9999)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(HostPort)
s.listen(1)
while True:
    conn, addr = s.accept()
    while True:
        cmd = conn.recv(1024).decode()
        if cmd == 'get':
            print('hello')
            cmd_result = os.popen('ls').read()
            conn.send(cmd_result.encode('utf-8'))
            File = conn.recv(1024).decode()
            File_size = os.stat(File).st_size        #返回的File_size是int类型
            print(type(File_size))
            conn.send(str(File_size).encode())
            f = open(File,'rb')                      # 用二进制读取文件内容
            for line in f:
                conn.send(line)                      # 已经是二进制内容格式,所以在
                #conn.close()
            f.close()
        if cmd == 'put':
            conn.send('sorry,you can\'t use this function!'.encode('utf-8'))

        if cmd == 'quit':
            conn.close()
        if  cmd == 'ls':
            print('error')
            print (cmd)
            cmd_result = os.popen(cmd).read()
            conn.send(cmd_result.encode('utf-8'))
        if  cmd == 'pwd':
            print('error')
            print (cmd)
            cmd_result = os.popen(cmd).read()
            conn.send(cmd_result.encode('utf-8'))

client端:

import socket
import os
import subprocess

hostport = ('127.0.0.1', 9999)
conn_ftp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn_ftp.connect(hostport)
while True:
    InputOne = input('Please input your command:\n>>> ')
    if InputOne == 'put':
        conn_ftp.send(InputOne.encode('utf-8'))
        server_reply = conn_ftp.recv(1024).decode()
        FtpServer.FileTransfer()

    if InputOne == 'get':
        print('go on')
        conn_ftp.send('get'.encode('utf-8'))
        server_reply = conn_ftp.recv(1024).decode()
        print(server_reply)
        File = input('Please choose a file: ')
        print('Waiting  download \033[1;35m%s\033[0m ' % File)
        conn_ftp.send(File.encode('utf-8'))  # 将文件名传给服务器,得到文件大小数据
        # File_size = int(conn_ftp.recv(1024).decode())
        File_size = int(conn_ftp.recv(1024).decode())
        print('文件大小为: \033[1;35m%s\033[0m' % File_size)

        # server端开始传输,返回文件大小
        Recv_size = 0

        # 下载到本地
        f = open(File + '_new', 'wb')
        # client 端确认传输,开始建立传输
        # 判断接收字节的大小,和传输完成判断
        while File_size > Recv_size:
            if File_size - Recv_size > 1024:
                size = 1024
            else:
                size = File_size - Recv_size
                print('Ready to receive the file......', size)
            File_content = conn_ftp.recv(size)  # 不用解码,直接接收(已经是二进制传输)
            Recv_size += len(File_content)
            # print (Recv_size/Total_size)
            f.write(File_content)  # 直接以二进制形式写入文件
        else:
            print('file is download complate!')
            f.close()


    if InputOne == 'quit':
        break
    if InputOne != 'get':
        conn_ftp.send(InputOne.encode('utf-8'))
        server_reply = conn_ftp.recv(1024).decode()
        print(server_reply)


客户端登陆自定义模块:

UserLogin.py

#!/usr/bin/env python3.4
import pymysql
def UserLogin():
    conn = pymysql.connect(host='localhost',user='root',passwd='1234qwer',db='python',port=3306,charset='utf8')
    cur = conn.cursor() #获取一个游标
    cur.execute('select * from user_login')
    data = cur.fetchall()
    user = {}
    for d in data:
        name = d[1]
        password = d[2]
        user[name] = password
        #print(user)
    count_input = input ('Please input your account: ')
    i = 0
    for key,value in user.items():
        if key == count_input:
            #passwd_input = input('Please input '+count_input+' \'s password: ')
            passwd_input = input('Please input your password: ')
            if passwd_input == user[count_input]:
                print ('Welcome to ftp!')
            else:
                print ('This is a error password! Please input your password again!')
                break
        else:
            i += 1
            if i > len(user):
                print('We dont\'t have this count! Please input again!')
                break
    cur.close()
    conn.close()
if __name__ == '__main__':
        UserLogin()

运行时问题报错和排查:

客户端运行问题:没有pymysql模块

所以在控制台中pip安装pymysql模块:pip3.6 install pymysql 


安装完成后,可以正常运行,运行截图如下(先运行服务器端,再运行客户端):

server端:

# cd  /data/ntalker/python/day5-socket/ftp/server

#  python server_ftp.py


client端:

#cd  /data/ntalker/python/day5-socket/ftp/client

1、登陆功能:


2、从服务器下载文件功能:

python3 用socket编写ftp_第1张图片

启动服务器后,运行client文件:

验证文件:并查看文件内容无误;

python3 用socket编写ftp_第2张图片

python3 用socket编写ftp_第3张图片

测试完成!!

你可能感兴趣的:(python,项目)