socketserver paramiko
SocketServer
socket有个问题,无法支持多用户(多并发)所以就出现了SocketServer
SocketServer模块简化了编写网络服务器,SocketServer是对socket的再封装,使其更简单
socketserver.TCPServer(server_address,RequestHandlerClass,bind_and_activate=True)(最常用)
socketserver.UDPServer(server_address,RequestHandlerClass,bind_and_activate=True)(这个比较少用)
socketserver.UnixStreamServer(server_address,RequestHandlerClass,bind_and_activate=True)(更少用,本机内不同进程交互使用)
socketserver.UnixDatagramServer(server_address,RequestHandlerClass,bind_and_activate=True)(更少用)
以上四个都继承了BaseServer
创建一个socketserver至少分以下几步:
1.你必须创建一个请求处理类,并且这个类要继承类BaseRequestHandler,重写父类的handle()方法(跟客户端所有的交互都是这个方法里面写的)
2.你必须要实例化TCPServer等上面提出的类其中一个,并且传递server ip和你上面创建的请求处理类给这个TCPServer(这里以TCPServer为例子)
3.
server.handle_request()#只处理一个请求(这个一般不用)
server.serve_forever()#处理多个请求,永远执行
4.关闭socketserver
import socketserver # 每个客户端请求过来都会实例化MyTCPHandler # 必须要写一个自己的处理类,这个类必须继承BaseRequestHandler并且重写handle()方法 class MyTCPHandler(socketserver.BaseRequestHandler): # 重写handle()方法 def handle(self): while True: try: # self.request.recv 接收客户端数据 self.data = self.request.recv(1024).strip() print("{}wrote:".format(self.client_address)) print(self.data) # 将数据变成大写,再发送回客户端 self.request.send(self.data.upper()) except ConnectionResetError as e: print("客户端%s已经断开"%format(self.client_address),e) break if __name__ == '__main__': HOST,PORT = "localhost",9999 # 实例化TCPServer,将ip地址以及端口传递,还有刚刚定义的类也传递 # TCPServer只是单对单的服务 # server = socketserver.TCPServer((HOST,PORT),MyTCPHandler) # ThreadingTCPServer才是多线程 server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) # 建立多进程,一般用于linux操作系统,windows没有 # server = socketserver.ForkingTCPServer((HOST, PORT), MyTCPHandler) print("服务器已经启动".center(70, "=")) # 处理多个客户端请求 server.serve_forever()
import socket client = socket.socket() client.connect(("localhost",9999)) while True: msg = input("输入:").strip() if not msg: continue client.send(msg.encode("utf-8")) recv = client.recv(1024) print(recv.decode())
HOST = 0.0.0.0#这样写是避免了一台机器多个网卡的情况,只有特定的ip地址才能访问
socketserver的方法
fileno()#返回文件描述符
,一般用不到
handle_request()#处理单个请求,一般不用
server_forever(poll_interval = 0.5)#一直处理请求知道收到一个明确的shutdown()请求,每0.5秒检查一下shutdown信号。这里默认就是0.5
server_actions()#收到shutdown请求后,会自动调用server_actions()去清理子进程的垃圾。
shutdown()#告诉server_forever()让他停掉,然后清理垃圾
server_close()#关闭服务器
address_family#地址簇
RequestHandlerClass #请求处理类
server_address #ip地址
socket#之前学习的socket
allow_reuse_address#允许地址重用,即服务器断开了,但是客户端依然连接的情况,强制断开客户端地址,使得服务器地址能够再次使用,不报错;不然需要等几十秒才能自动断开
request_queue_size#队列大小
socket_type #协议类型
timeout#超时时间,一般不使用
finish_request()#一般不使用
get_request()#获取请求的实例以及ip地址,一般不使用
handle_error(request,client_address)#处理错误,一般也不怎么使用
handle_timeout()#一般不使用
process_request(requet,client_address)#处理单个请求用
server_activate()#没用过
server_bind()#内部调用,一般用不到
paramiko
查看linux地址:ifconfig
netstat -tulnp|grep 22 (默认远程linux系统端口)
netstat -tulnp|grep ssh (查看ssh加密端口)
修改linux的ssh端口:
关闭防火墙:
systemctl stop firewalld.service
修改ssh端口等信息的地方
vim /ect/ssh/sshd_config
远程其他linux系统(若是无法远程,请登录上面修改允许被远程)
修改PermitRootLogin no-->改为yes
ssh root@192.168.5.174 -p22
linux系统文传送文件给其他linux系统
-rp:r代表即使是目录也能传送,p代表将权限也复制过去
:/tmp代表复制到另一台linux系统的目录
scp -rp -P22 root@192.168.5.174:/tmp
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.5.175',port=22,username='root',password='Choice123')
import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='192.168.5.175',port=22,username='root',password='Choice123') # 执行命令 # stdin:标准输入 # stdout:标准输出 # stderr :错误输出,与stdout只有一个显示,正确则显示stdout,错误显示这个 stdin,stdout,stderr = ssh.exec_command('ifconfig') # 获取命令结果 result = stdout.read() result2 = stderr.read() print(result.decode()) print(result2.decode()) ''' 三元运算写法 res,err = stdout.read(),stderr.read() result = res if res else err ''' # 关闭连接 ssh.close()
linxu系统对应路径如图
import paramiko,os path = os.path.dirname(os.path.abspath(__file__)) print(path) # 这里是传送ftp所以,就使用Transport transport = paramiko.Transport(('192.168.5.175',22)) # 链接 transport.connect(username='root',password='Choice123') # 把已经建立好的链接,给SFTPClient.from_transport sftp = paramiko.SFTPClient.from_transport(transport) # 将location.py上传至服务器 /tm/test.py # sftp.put('/tmp/location.py','tmp/test.py') upload_file = os.path.join(path,'2.cfg') print(upload_file) print(os.path.isfile(upload_file)) # sftp.put('1','tmp/1') # 将remove_path 下载到本地 local_path # sftp.get('remove_paty','local_path') sftp.get('/parser.out',upload_file) transport.close()