一、socketserver实现多并发

socket只能实现单进程通讯,要实现多进程同时和服务端通讯就要使用socketserver。

代码如下:

 import socket
client = socket.socket()
client.connect(("localhost",9000))
while True:
choice = input(">>>:")
if len(choice) == 0:continue
client.send(choice.encode())
recv = client.recv(1024)
print("recved:",recv.decode())
 #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Liumj
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
self.data = self.request.recv(1024).strip()
print(self.client_address[0])
print(self.data)
self.request.sendall(self.data.upper())
if __name__ =="__main__":
HOST,PORT = "localhost",9000
server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
server.serve_forever()

二、FTP程序开发

1.服务端代码

 import socketserver
import configparser
from conf import settings
import os
import hashlib
import time
t = time.strftime("%H_%M_%S") STATUS_CODE = {
250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
251 : "Invalid cmd ",
252 : "Invalid auth data",
253 : "Wrong username or password",
254 : "Passed authentication",
255 : "Filename doesn't provided",
256 : "File doesn't exist on server",
257 : "ready to send file",
258 : "md5 verification",
}
import json
class FTPHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
self.data = self.request.recv(1024).strip()
print(self.client_address[0])
print(self.data)
if not self.data:
print("client closed...")
break
data = json.loads(self.data.decode())
if data.get('action') is not None:
print("---->",hasattr(self,"_auth"))
if hasattr(self,"_%s"%data.get('action')):
func = getattr(self,"_%s"% data.get('action'))
func(data)
else:
print("invalid cmd")
self.send_response(251)
else:
print("invalid cmd format")
self.send_response(250) def send_response(self,status_code,data=None):
'''向客户端返回数据'''
response = {'status_code':status_code,'status_msg':STATUS_CODE[status_code]}
if data:
response.update( data )
self.request.send(json.dumps(response).encode()) def _auth(self,*args,**kwargs):
data = args[0]
if data.get("username") is None or data.get("password") is None:
self.send_response(252) user =self.authenticate(data.get("username"),data.get("password"))
if user is None:
self.send_response(253)
else:
print("passed authentication",user)
self.user = user
self.send_response(254)
def authenticate(self,username,password):
'''验证用户合法性,合法就返回用户数据''' config = configparser.ConfigParser()
config.read(settings.ACCOUNT_FILE)
if username in config.sections():
_password = config[username]["Password"]
if _password == password:
print("pass auth..",username)
config[username]["Username"] = username
return config[username] def _put(self,*args,**kwargs):
"client send file to server"
data = args[0]
# if data.get('filename') is None:
# self.send_response(255)
user_home_dir = "%s/%s" % (settings.USER_HOME, self.user["Username"])
file_abs_path = "%s/%s" % (user_home_dir, data.get('filename'))
print("file abs path", file_abs_path)
print("server.....")
self.send_response(257)
received_size = 0
total_size = int(self.request.recv(1024))
file_obj = open(file_abs_path+t, "wb")
#print("zhaodao.....")
while received_size < total_size:
data = self.request.recv(4096)
received_size +=len(data)
file_obj.write(data)
else:
print("---recv done...")
file_obj.close() def _get(self,*args,**kwargs):
data = args[0]
if data.get('filename') is None:
self.send_response(255)
user_home_dir = "%s/%s" %(settings.USER_HOME,self.user["Username"])
file_abs_path = "%s/%s" %(user_home_dir,data.get('filename'))
print("file abs path",file_abs_path) if os.path.isfile(file_abs_path):
file_obj = open(file_abs_path,"rb")
file_size = os.path.getsize(file_abs_path)
self.send_response(257,data={'file_size':file_size})
self.request.recv(1) #等待客户端确认 if data.get('md5'):
md5_obj = hashlib.md5()
for line in file_obj:
self.request.send(line)
md5_obj.update(line)
else:
file_obj.close()
md5_val = md5_obj.hexdigest()
self.send_response(258,{'md5':md5_val})
print("send file done....")
else:
for line in file_obj:
self.request.send(line)
else:
file_obj.close()
print("send file done....")
else:
self.send_response(256) def _ls(self,*args,**kwargs):
pass def _cd(self, *args, **kwargs):
pass if __name__ == "__main__":
HOST, PORT = "localhost", 9000

ftp_server

2.客户端代码

 import socket
import os ,json
import optparse
import getpass
import hashlib
import sys STATUS_CODE = {
250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
251 : "Invalid cmd ",
252 : "Invalid auth data",
253 : "Wrong username or password",
254 : "Passed authentication",
255 : "Filename doesn't provided",
} class FTPClient(object):
def __init__(self):
parser = optparse.OptionParser()
parser.add_option("-s","--server", dest="server", help="ftp server ip_addr")
parser.add_option("-P","--port",type="int", dest="port", help="ftp server port")
parser.add_option("-u","--username", dest="username", help="username")
parser.add_option("-p","--password", dest="password", help="password")
self.options , self.args = parser.parse_args()
self.verify_args(self.options,self.args)
self.make_connection() def make_connection(self):
self.sock = socket.socket()
self.sock.connect((self.options.server,self.options.port)) def verify_args(self, options,args):
'''校验参数合法型'''
if options.username is not None and options.password is not None:
pass
elif options.username is None and options.password is None:
pass
else:
#options.username is None or options.password is None:
exit("Err: username and password must be provided together..") if options.server and options.port:
#print(options)
if options.port >0 and options.port <65535:
return True
else:
exit("Err:host port must in 0-65535") def authenticate(self):
'''用户验证'''
if self.options.username:
print(self.options.username,self.options.password)
return self.get_auth_result(self.options.username, self.options.password)
else:
retry_count = 0
while retry_count <3:
username = input("username:").strip()
password = input("password:").strip()
return self.get_auth_result(username,password) def get_auth_result(self,user,password):
data = {'action':'auth',
'username':user,
'password':password} self.sock.send(json.dumps(data).encode())
response = self.get_response()
if response.get('status_code') == 254:
print("Passed authentication!")
self.user = user
return True
else:
print(response.get("status_msg")) def get_response(self):
'''得到服务器端回复结果'''
data = self.sock.recv(1024)
print("server res", data)
data = json.loads(data.decode())
return data def interactive(self):
if self.authenticate():
print("---start interactive iwth u...")
while True:
choice = input("[%s]:"%self.user).strip()
if len(choice) == 0:continue
cmd_list = choice.split()
if hasattr(self,"_%s"%cmd_list[0]):
func = getattr(self,"_%s"%cmd_list[0])
func(cmd_list)
else:
print("Invalid cmd.") def __md5_required(self,cmd_list):
'''检测命令是否需要进行MD5验证'''
if '--md5' in cmd_list:
return True
def show_progress(self,total):
received_size = 0
current_percent = 0
while received_size < total:
if int((received_size / total) * 100 ) > current_percent :
print("#",end="",flush=True)
current_percent = int((received_size / total) * 100 )
new_size = yield
received_size += new_size
def _get(self,cmd_list):
print("get--",cmd_list)
if len(cmd_list) == 1:
print("no filename follows...")
return
data_header = {
'action':'get',
'filename':cmd_list[1]
}
if self.__md5_required(cmd_list):
data_header['md5'] = True self.sock.send(json.dumps(data_header).encode())
response = self.get_response()
print(response)
if response["status_code"] ==257:#ready to receive
self.sock.send(b'')#send confirmation to server
base_filename = cmd_list[1].split('/')[-1]
received_size = 0
file_obj = open(base_filename,"wb")
if self.__md5_required(cmd_list):
md5_obj = hashlib.md5()
progress = self.show_progress(response['file_size']) #generator
progress.__next__()
while received_size < response['file_size']:
data = self.sock.recv(4096)
received_size += len(data)
try:
progress.send(len(data))
except StopIteration as e:
print("100%")
file_obj.write(data)
md5_obj.update(data)
else:
print("----->file rece done----")
file_obj.close()
md5_val = md5_obj.hexdigest()
md5_from_server = self.get_response()
if md5_from_server['status_code'] == 258:
if md5_from_server['md5'] == md5_val:
print("%s 文件一致性校验成功!" % base_filename)
#print(md5_val,md5_from_server) else:
progress = self.show_progress(response['file_size']) #generator
progress.__next__() while received_size < response['file_size']:
data = self.sock.recv(4096)
received_size += len(data)
file_obj.write(data)
try:
progress.send(len(data))
except StopIteration as e:
print("100%") else:
print("----->file recv done----")
file_obj.close()
def _put(self,cmd_list):
print("put----",cmd_list)
if len(cmd_list) == 1:
print("no filename follows...")
return
data_header = {
'action':'put',
'filename':cmd_list[1]
}
self.sock.send(json.dumps(data_header).encode())
#response = self.get_response()
#print(response)
print("client......")
file_obj = open(cmd_list[1],"rb")
file_size = os.stat(cmd_list[1]).st_size
print(file_size)
self.sock.send(str(file_size).encode())
self.sock.recv(1024) #等待服务端确认
progress = self.show_progress(file_size) # generator
progress.__next__()
for i in file_obj:
self.sock.send(i)
else:
try:
progress.send(int(file_size))
except StopIteration as e:
print("100%")
file_obj.close()
print("send done...")
if __name__ == "__main__":
ftp = FTPClient()
ftp.interactive() #交互

ftp_client

Python网络编程学习_Day9的更多相关文章

  1. python网络编程学习《一》

    最近,刚实习完,很喜欢实验楼,但是自己的方向仍然不能确定,自己觉得可选择的空间很大,尽管已经是大四的人了,想到别人都在忙着买职业装,买高跟鞋面试,学习化妆什么的,看看自己,反而开始慢慢关注运动,食疗以 ...

  2. python网络编程学习笔记(三):socket网络服务器(转载)

    1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象  建立socket对 ...

  3. Python网络编程学习_Day11

    一.协程 1.理论知识 协程,又称伪线程,是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈. ...

  4. Python网络编程学习_Day10

    一.进程与线程 1.区别 进程:一个程序要运行时所需要的所有资源的集合,进程是资源的集合. 一个进程至少需要一个线程,这个线程称为主线程 一个进程里面可以有多个线程 两个进程之间的数据是完全独立,不能 ...

  5. python网络编程学习笔记(10):webpy框架

    转载请注明:@小五义http://www.cnblogs.com/xiaowuyi django和webpy都是python的web开发框架.Django的主要目的是简便.快速的开发数据库驱动的网站. ...

  6. Python网络编程基础|百度网盘免费下载|零基础入门学习资料

    百度网盘免费下载:Python网络编程基础|零基础学习资料 提取码:k7a1 目录: 第1部分 底层网络 第1章 客户/服务器网络介绍 第2章 网络客户端 第3章 网络服务器 第4章 域名系统 第5章 ...

  7. Python学习(22)python网络编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

  8. 《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档

    Foundations of Python Network Programing,Third Edition <python网络编程>,本书中的代码可在Github上搜索fopnp下载 本 ...

  9. Python 网络编程相关知识学习

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

随机推荐

  1. ASP.Net页面传值比较

    ASP.Net页面传值比较   作为一个ASP.Net程序员,尤其是搞B/S开发的,对于不同页面之间变量值的传递用的非常广泛,而掌握不同方式之间的区别和特点也就很有必要.本文将针对这一知识点做一个简单 ...

  2. DOM(二) 判断节点包含关系

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. rebbitmq-RPC(C#)

    RPC(Remote Procedure Call Protocol)——远程过程调用协议 运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步: 1.调用客户端句柄:执行传送参数 2.调 ...

  4. usaco1.1.1Your Ride Is Here(入门题)

    一下是我很久很久之前刷的题目...随便扔在这里啦.. Description 一个众所周知的事实,在每一慧星后面是一个不明飞行物UFO.这些不明飞行物时常来收集来自在地球上忠诚的支持者.不幸的是,他们 ...

  5. MVC 4 插件化架构简单实现

    转ASP.NET MVC 4 插件化架构简单实现-思路篇   用过和做过插件的都会了解插件的好处,园子里也有很多和讨论,但大都只些简单的加载程序集什么的,这里主要讨论的就是使用 ASP.NET MVC ...

  6. LDAP查询实例

      /// <summary> /// 搜索AD人员 /// </summary> /// <param name="keyWords">搜索部 ...

  7. 使用C++做算法时,对内存的管理的办法

    使用C++做算法时,对内存的管理的办法 最近老是在想C++的内存控制机制,查了一些资料所以有点想法,自己记录一下免得以后自己忘了. 1. 需求 在做线性代数的算法时,首要的就实现Matrix这个类.由 ...

  8. 整合MVVM框架(Prism)

    整合MVVM框架(Prism) 我们基础的框架已经搭建起来了,现在整合MVVM框架Prism,在ViewModel做一些逻辑处理,真正把界面设计分离出来. 这样方便我们系统开发分工合作,同时提高系统可 ...

  9. VC 编程ANSI环境下读写Unicode文件

    没有注意到文件编码的不同会产生这么多的问题,在动手以前查询了很多资料,在本博客中收藏了不少先辈的成果,在这里一并表示致敬!       关于ANSI和Unicode编码的原理在这里也不说了,主要讲下如 ...

  10. Hibernate3.0中的session.find()问题

    我被Session.find()的方法困扰了好几天,今天才看到新的Hibernate里没有了Session.find()方法. 现在转载在此,方便你我. 查询性能往往是系统性能表现的一个重要方面,查询 ...