# server import asyncore # 源码分析很有用 import struct import threading import socket class CJSocket(asyncore.dispatcher): def __init__(self, sock, maps): super(CJSocket, self).__init__(sock=sock, map=maps) self.send_buffer = b'' def writable(self): return len(self.send_buffer) > 0 def handle_write(self): sent = self.send(self.send_buffer) self.send_buffer = self.send_buffer[sent:] def auto_send(self, lst1, lst2): buff = b'' for i in range(len(lst1)): buff += struct.pack(lst1[i], lst2[i]) self.send_buffer += buff def readable(self): return True def handle_read(self): # data = self.recv(819 2) data = self.recv(4) data += self.recv(struct.unpack('!I', data[0:4])[0] - 4) if len(data) < 12: return sum_len = struct.unpack('!I', data[0:4])[0] # 总长 cmd_id = struct.unpack('!I', data[4:8])[0] # 命令 seq_id = struct.unpack('!I', data[8:12])[0] # 序列号 print('sum_len:{sum_len} cmd_id:{cmd_id} seq_id:{seq_id}'.format(sum_len=sum_len, cmd_id=cmd_id, seq_id=seq_id)) if cmd_id == 1: # 回复hello typist = ['!I', '!I', '!I', '!I', '!5s'] values = [21, 2, seq_id, 5, b'hello'] self.auto_send(typist, values) elif cmd_id == 3: # 回复bye msg_len = struct.unpack('!I', data[12:16])[0] msg = struct.unpack('!'+str(msg_len)+'s', data[16:16+msg_len])[0] msg = msg.decode() print('get the msg', msg) msg = list(msg) msg.reverse() msg = ''.join(msg) msg = msg.encode() typist = ['!I', '!I', '!I', '!I', '!'+str(msg_len)+'s'] values = [16+msg_len, 4, seq_id, msg_len, msg] self.auto_send(typist, values) elif cmd_id == 5: # 回复bye typist = ['!I', '!I', '!I', '!I', '!3s'] values = [19, 6, seq_id, 3, b'bye'] self.auto_send(typist, values) def handle_close(self) -> None: self.close() class CJServer(asyncore.dispatcher): def __init__(self, host, port, maps): asyncore.dispatcher.__init__(self, sock=None, map=maps) self.create_socket(family=socket.AF_INET, type=socket.SOCK_STREAM) self.map = maps # self.map[self._fileno] = self self.set_reuse_addr() self.bind((host, port)) self.listen(5) # listen(n)传入的值, n表示的是服务器拒绝(超过限制数量的)连接之前,操作系统可以挂起的最大连接数量。 self.handle_list = [] def handle_accepted(self, sock, adds): self.handle_list.append(CJSocket(sock=sock, maps=self.map)) print('现在CJ监听列表的socket是:', self.map) def handle_close(self): for i in range(len(self.handle_list)): self.handle_list[i].handle_close() self.close() class CJThread: cnt = 0 cjmap = {} def __init__(self, ip, port): self.ip = ip self.port = int(port) self.CJ = None self.thread = None def start(self): CJThread.cnt += 1 print('CJThread.cnt:', CJThread.cnt) self.CJ = CJServer(self.ip, self.port, CJThread.cjmap) print('现在的CJ监听列表:', CJThread.cjmap) if CJThread.cnt == 1: self.thread = threading.Thread(target=asyncore.loop, kwargs={'timeout': 1, 'use_poll': True, 'map': CJThread.cjmap}) self.thread.start() def stop(self): self.CJ.handle_close() CJThread.cnt -= 1 print('CJThread.cnt:', CJThread.cnt) print('现在的CJ监听列表:', CJThread.cjmap) CJThread1 = CJThread('127.0.0.1', 9999) CJThread1.start() input() # CJThread2 = CJThread('127.0.0.1', 8888) # CJThread2.start() # input() # CJThread1.stop() # input() # CJThread2.stop() # input() # CJThread1 = CJThread('127.0.0.1', 8888) # CJThread1.start() # input() # CJThread2 = CJThread('127.0.0.1', 9999) # CJThread2.start() # input() CJThread1.stop() # input() # CJThread2.stop() # input()
# client import asyncore import socket import struct class HTTPClient(asyncore.dispatcher): def __init__(self, host): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect((host, 9999)) self.buffer = b'' typist = ['!I', '!I', '!I'] values = [12, 1, 6] for i in range(len(typist)): self.buffer += struct.pack(typist[i], values[i]) typist = ['!I', '!I', '!I', '!I', '!4s'] values = [20, 3, 7, 4, b'abcd'] for i in range(len(typist)): self.buffer += struct.pack(typist[i], values[i]) typist = ['!I', '!I', '!I'] values = [12, 5, 8] for i in range(len(typist)): self.buffer += struct.pack(typist[i], values[i]) def handle_connect(self): print('connect success') def handle_close(self): self.close() print('close success') def readable(self) -> bool: return True def handle_read(self): data = self.recv(4) data += self.recv(struct.unpack('!I', data[0:4])[0] - 4) print(data) def writable(self): return len(self.buffer) > 0 def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:] client = HTTPClient('127.0.0.1') asyncore.loop()多线程两种写法
# 一、直接使用threading import threading def action(maxs): for j in range(maxs): print(threading.current_thread().getName() + " " + str(j)) t1 = threading.Thread(target=action, name='t1', args=(4,)) t2 = threading.Thread(target=action, name='t2', args=(5,)) for i in range(10): print(threading.current_thread().getName() + " " + str(i)) if i == 3: t1.start() t2.start() print('主线程执行完成!') t1.join() t2.join() # 二、继承使用threading class MyThread(threading.Thread): # 可维护成员cnt,可获得线程返回值self.result cnt = 0 def __init__(self, target, args=()): super(MyThread, self).__init__() self.result = "default result" self.target = target self.args = args def run(self): MyThread.cnt += 1 print('MyThread.cnt', MyThread.cnt) self.result = self.target(*self.args) MyThread.cnt -= 1 print('MyThread.cnt', MyThread.cnt) @staticmethod def myfunc(x): for index in range(x): print(threading.current_thread().getName(), index) return x + 1 mt1 = MyThread(target=MyThread.myfunc, args=(5,)) mt2 = MyThread(target=MyThread.myfunc, args=(7,)) mt1.start() mt2.start() mt1.join() mt2.join() print(mt1.result, mt2.result) ''' 关于主线程结束时子线程是否会强制结束: a线程创建b线程,如果a线程不是守护线程,那么实际上a和b两个线程没有必然联系。 b线程未结束,a线程该结束的时候还是会结束,除非a线程是守护线程,是的话会自动join。 main线程并不是守护线程,是由虚拟机创建的,也不能设置成守护线程。 而join是让a线程阻塞等b线程跑完为止,未必是需要的。 补充一点: python中守护进程也称为后台进程:当程序中主线程及所有非守护线程执行结束时, 守护线程(例如一直死循环输出hello)也会随之消亡,程序将结束运行。 ''' # 话说,在java中应该使用接口左斜线、正斜线、左斜杠、正斜杠 / 右斜线、反斜线、右斜杠、反斜杠
# cjgang.py import os # win10下 # 假设当前py文件同目录下有一个test文件夹,test下有一个logs文件夹,我要创建一个cj文件夹 os.system("mkdir testlogscj1") # 这个是可以的,因为l与c都不是转义符 # 假设当前py文件同目录下有一个test文件夹,test下有一个logs文件夹,我要创建一个nj文件夹 # os.system("mkdir testlogsnj0") # 这个是不行的 os.system("mkdir test\logs\nj1") # 这个是可以的 os.system(r"mkdir testlogsnj2") # 这个也是可以的,r就表示无转义符 # linux下 # 假设当前py文件同目录下有一个test文件夹,test下有一个logs文件夹,我要创建一个nj文件夹 os.system("mkdir test/logs/nj3") # 这个是可以的,因为没有就没有转义符 # 特别说明 # 其实上面的写法不太好,表示目录时应在路径末尾加斜框/或反斜杠,即: os.system("mkdir test\logs\nj4\") os.system("mkdir test/logs/nj5/") # 综上 # 在win执行本程序,会生成cj1,nj1,nj2,nj4 # 在linux执行本程序,会生成nj3,nj5 ''' 补充:关于网址中末层的/ http://www.abc.com/abc http://www.abc.com/abc/ 末尾带斜杠 / 的是目录/abc/,不带的是文件/abc,是两个不同的地址。 如访问/abc/,服务器会根据规则访问改目录下的默认首页文件,如/abc/index.html文件。 由于含index的文件可能有多个,如index.htm或index.jsp,服务器会根据规则选择优先级最高的显示。 如访问/abc,服务器则会寻找/abc文件,如果没有就把 abc 当做目录处理。 显然,是目录就该有末/,不是目录就该写http://www.abc.com/abc/index.html,才是比较好的习惯。 '''SSH 传输
# ssh # 第一部分:文件命令 import paramiko t = paramiko.Transport(('100.115.157.101', 22)) t.connect(username='root', password='Huawei12#$') chan = paramiko.SFTPClient.from_transport(t) print(chan.put(localpath='config.json', remotepath='/root/CJ/444/config2.json')) # 上传文件 print(chan.stat(path='/root/CJ/444/config2.json')) # 查看文件属性 chan.get(remotepath='/root/CJ/444/config2.json', localpath='config3.json') # 下载文件 chan.mkdir(path='/root/CJ/444/666/', mode=paramiko.common.o777) # 建立目录 print(chan.listdir(path='/root/CJ/444/')) # 查看目录 print(chan.listdir_attr(path='/root/CJ/444/')) # 查看目录下文件以及子目录的详细信息,可能会报异常 chan.rmdir(path='/root/CJ/444/666/') # 删除目录 chan.remove(path='/root/CJ/444/config2.json') # 删除文件 chan.close() # 关闭通道 t.close() # 第二部分:控制命令第一种写法(SSHClient) import paramiko t = paramiko.Transport(('100.115.157.101', 22)) t.connect(username='root', password='Huawei12#$') ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy) ssh._transport = t stdin, stdout, stderr = ssh.exec_command('pwdnpwdn') print(stdout.read()) # 注意read完缓冲区就会清空 ssh.close() t.close() # 第三部分:控制命令第二种写法(open_session) import paramiko t = paramiko.Transport(('100.115.157.101', 22)) t.connect(username='root', password='Huawei12#$') chan = t.open_session() chan.settimeout(15) chan.invoke_shell() chan.send(b'mkdir /root/CJ/444/555n') chan.send(b'cd /root/CJ/444/nmkdir 666n') chan.close() t.close() ''' 个人感觉:用SSHClient可以解决一切问题,优先使用 还有就是,linux下删除直接用rm -rf即可,无论文件还是文件夹,无论文件夹是否为空,皆可用 '''关于换行
经测试,win与linux都是n即可,例如下面:
补充说明一下:我是用notepad++打开的,以无bom的utf-8保存,如果是用记事本保存带bom的话要用utf-8-sig:
补充:win记事本默认ANSI格式,即GBK国标,没有中文时与无bom的utf-8相同