python实现类似ftp传输文件的网络程序示例
此代码在linux上编写,适用于linux,windows下需要更改几个命令。
1、客户端输入ip,端口,可服务器端进行连接,被要求输入用户名和密码进行验证。
2、使用独立的模块来验证登录用户(技术有限,不支持客户端创建用户),用户名:ftpuser 密码:userlogin
2、客户端登录验证成功后,可使用?或者help查看可使用的命令。
ftpserver.py
#!/usr/bin/env python
#-*- coding:utf-8
"program for ftp server"
from socketserver import *
from time import *
import os
import loginauth
class myftp(streamrequesthandler):
def handle(self):
try:
while true:
sleep(0.5)
self.request.sendall('auth')
name = self.request.recv(bufsiz)
sleep(0.5)
self.request.sendall('pauth')
password = self.request.recv(bufsiz)
print name,password
auth_result = loginauth.user_create(name,password)
print auth_result
if auth_result == 0:
self.request.sendall('ok2login')
break
elif auth_result == 1:
self.request.sendall('fail2login')
continue
while true:
recv_data = self.request.recv(bufsiz).split()
if recv_data[0] == 'rls':
result = os.popen('ls -l ./').read()
self.request.sendall(result)
continue
if recv_data[0] == '?' or recv_data[0] == 'help':
send_help = '''\033[32;1m
?\help: get help.
get: downlaod file from remote server.
send: send local file to remote server.
ls: list local file.
rls: list remote server file.
quit\exit: quit the application.
\033[0m'''
self.request.sendall(send_help)
continue
if recv_data[0] == 'send':
filename = recv_data[1]
self.request.sendall('ok2send')
recv_data = self.request.recv(bufsiz)
file2w = open(filename,'wb')
file2w.write(recv_data)
file2w.flush()
file2w.close()
self.request.sendall('\033[33;1mfile transfer successed!!!\033[0m')
continue
if recv_data[0] == 'get':
filename = recv_data[1]
if os.path.isfile(filename):
self.request.sendall('ok2get')
if self.request.recv(bufsiz) == 'ok2send':
self.request.sendall('sending')
sleep(0.5)
file_data = open(filename,'rb')
file_tmp = file_data.read()
self.request.sendall(file_tmp)
sleep(1)
self.request.sendall('\033[33;1mdownloading complete!\033[0m')
file_data.close()
else:
self.request.sendall('fail2get')
if self.request.recv(bufsiz) == 'ack':
self.request.sendall('\033[31;1m%s not found\033[0m'% filename)
except :
pass
if __name__ == '__main__':
host,port = '',9889
addr = (host,port)
bufsiz = 8192
try:
server = threadingtcpserver(addr,myftp)
server.serve_forever()
except keyboardinterrupt:
server.shutdown()
loginauth.py
#!/usr/bin/env python
#-*- coding:utf-8
#filename:userlogin.py
"program for userlogin"
import sys,time
import cpickle as pickle
#if it's your first running this program,use userdb = {}
#if it is not your first running this program,use userdb = pickle.load(open('userdb','rb'))
userdb = pickle.load(open('userdb','rb'))
#userdb = {}
class userdb(object):
def __init__(self,username,password,time):
self.username = username
self.passwd = password
self.time = time
def save_user(self):
userdb[self.username] = [self.passwd,self.time]
pickle.dump(userdb,open('userdb','wb'),true)
def update_db(self):
pass
def user_create(name,passwd = ''):
if name in userdb:
if passwd == userdb[name][0]:
p = userdb(name,passwd,time.time())
p.save_user()
return 0
else:
return 1
else:
#p = userdb(name,passwd,time.time())
#p.save_user()
return 1
if __name__ == '__main__':
user_create(name,password)
ftpclient.py
#!/usr/bin/env python
#-*- coding:utf-8
"program for ftp client."
from socket import *
from time import sleep
import os
def auth():
while 1:
try:
recv_msg = s.recv(bufsiz)
if recv_msg == 'auth':
user = str(raw_input('please input your username: ')).strip()
s.sendall(user)
if s.recv(bufsiz) == 'pauth':
pass = str(raw_input('please input your password: ')).strip()
s.sendall(pass)
recv_msg1 = s.recv(bufsiz)
if recv_msg1 == 'ok2login':
print '\033[33;1mlogin success!!!\033[0m'
break
elif recv_msg1 == 'fail2login':
print '\033[33;1mlogin failure!!!\033[0m'
continue
else:
continue
except:
return 'error'
def switch():
while true:
input = str(raw_input('ftp> ')).strip()
if len(input) == 0:continue
elif input == 'quit' or input == 'exit':
s.close()
break
elif input == '?' or input == 'help':
s.send(input)
recv_data = s.recv(bufsiz)
print recv_data
continue
elif input == 'get' or input == 'send':
print '\033[31;1myou must specified filename!!\033[0m'
continue
elif input == 'ls':
cmd = os.popen('ls -l ./').read()
print cmd
continue
elif input == 'rls':
s.send(input)
recv_data = s.recv(bufsiz)
print recv_data
continue
elif input.split()[0] == 'send':
filename = input.split()[1]
if os.path.isfile(filename):
print 'sending %s......'% filename
s.sendall(input)
re_data = s.recv(bufsiz)
if re_data == 'ok2send':
file_data = open(filename,'rb')
file_tmp = file_data.read()
file_data.close()
s.sendall(file_tmp)
sleep(0.5)
recv_data = s.recv(bufsiz)
print recv_data
continue
else:continue
else:
print '\033[31;1m%s not found!\033[0m'% filename
elif input.split()[0] == 'get':
filename = input.split()[1]
s.sendall(input)
msg1 = s.recv(bufsiz)
if msg1 == 'ok2get':
s.sendall('ok2send')
msg2 = s.recv(bufsiz)
if msg2 == 'sending':
file_data = s.recv(bufsiz)
file2w = open(filename,'wb')
file2w.write(file_data)
file2w.flush()
file2w.close()
msg3 = s.recv(bufsiz)
print msg3
continue
elif msg1 == 'fail2get':
s.send('ack')
msg4 = s.recv(bufsiz)
print msg4
continue
else:
continue
if __name__ == '__main__':
#default 127.0.0.1
host = str(raw_input('server ip: ')).strip()
#defautl 9889
port = int(raw_input('server port: '))
addr = (host,port)
bufsiz = 8192
s = socket(af_inet,sock_stream)
try:
s.connect(addr)
except :
pass
if auth() == 'error':
print 'connection refused.'
else:
switch()