socketserver

Posted 雨之愿风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socketserver相关的知识,希望对你有一定的参考价值。

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()
socketserver例子

 

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())
client

 

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()
ssh加密访问linux

 

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()
ssh_ftp

 

以上是关于socketserver的主要内容,如果未能解决你的问题,请参考以下文章

socketserver.py代码阅读笔记

socketserver.py代码阅读笔记

socketserver实现并发

socketserver

Python网络编程篇之socketserver

socketserver源码解析和协程版socketserver