标签:
复习下socket 编程的步骤:
动态导入模块:
1 实践: 2 1 lib下的aa 3 def test(): 4 print("hehe") 5 class C(object): 6 name = "yang" 7 def __init__(self): 8 self.name = ‘shenyang‘
9 lib外的test 10 import importlib 11 dd = importlib.import_module(‘lib.aa‘) 12 dd.test() 13 print(dd.C().name)
运行:
判断错误
和 if 判断 一样 但是更简洁,一句话就OK
继续socket 编程:
1 #!/usr/bin/env python3 2 # Author: Shen Yang 3 import socket,os 4 ip_address = ‘192.168.16.10‘ 5 port = 8888 6 bind_address = (ip_address,port) 7 server = socket.socket() 8 server.bind(bind_address) 9 server.listen() 10 while True: 11 conn,addr = server.accept() 12 while True: 13 data = conn.recv(1024).decode() 14 if not data: 15 print("丢失连接") 16 break 17 print("这是来自",addr,data) 18 cmd_res = os.popen(data).read() 19 conn.send(str(len(cmd_res.encode(‘utf-8‘))).encode(‘utf-8‘)) 20 conn.send(cmd_res.encode(‘utf-8‘)) 21 server.close()
客户端
1 #!/usr/bin/env python3 2 # Author: Shen Yang 3 import socket 4 ip_address = ‘192.168.16.10‘ 5 # ip_address = ‘192.168.81.133‘ 6 port = 8888 7 conn_address = (ip_address,port) 8 client = socket.socket() 9 client.connect(conn_address) 10 while True: 11 cmd = input(":> ").encode(‘utf-8‘) 12 if len(cmd) == 0: 13 continue 14 client.send(cmd) 15 cmd_size = int(client.recv(1024).decode()) 16 print(cmd_size) 17 recov_size = 0 18 recov_data = b‘‘ 19 while recov_size < cmd_size: 20 data = client.recv(1024) 21 #print(data) 22 recov_size += len(data) 23 #print(recov_size) 24 recov_data += data 25 else: 26 print("收完了,大小",recov_size) 27 print(recov_data.decode()) 28 client.close()
上面的代码 在linux 发送 会出现粘包 客户端收到的是两个数据
客户端加发送过程:
#!/usr/bin/env python3 import socket,os ip_address = ‘192.168.81.133‘ port = 8888 bind_address = (ip_address,port) server = socket.socket() server.bind(bind_address) server.listen() while True: conn,addr = server.accept() while True: data = conn.recv(1024).decode() if not data: print("丢失连接") break print("这是来自",addr,data) cmd_res = os.popen(data).read() conn.send(str(len(cmd_res.encode(‘utf-8‘))).encode(‘utf-8‘)) ack = conn.recv(1024).decode() print(ack) conn.send(cmd_res.encode(‘utf-8‘)) server.close()
ssh_client
1 #!/usr/bin/env python3 2 import socket 3 ip_address = ‘192.168.81.133‘ 4 port = 8888 5 conn_address = (ip_address,port) 6 client = socket.socket() 7 client.connect(conn_address) 8 while True: 9 cmd = input(":> ").encode(‘utf-8‘) 10 if len(cmd) == 0: 11 continue 12 client.send(cmd) 13 cmd_size = int(client.recv(1024).decode()) 14 print(cmd_size) 15 client.send("收到大小".encode(‘utf-8‘)) 16 recov_size = 0 17 recov_data = b‘‘ 18 while recov_size < cmd_size: 19 data = client.recv(1024) 20 #print(data) 21 recov_size += len(data) 22 #print(recov_size) 23 recov_data += data 24 else: 25 print("收完了,大小",recov_size) 26 print(recov_data.decode()) 27 client.close()
使用 os.stat 获取文件详细信息,发送给客户端
另外一个解决粘包的方法:
只收指定大小的数据 永远不可能粘包
1 #!/usr/bin/env python3 2 import socket,os,hashlib 3 ip_address = ‘192.168.81.133‘ 4 port = 8888 5 bind_address = (ip_address,port) 6 server = socket.socket() 7 server.bind(bind_address) 8 server.listen() 9 while True: 10 conn,addr = server.accept() 11 while True: 12 print("等待新链接") 13 data = conn.recv(1024) 14 if not data: 15 print("丢失连接") 16 break 17 print("这是来自",addr,data) 18 cmd,file_name = data.decode().split() 19 if os.path.isfile(file_name): 20 m = hashlib.md5() 21 f = open(file_name,‘rb‘) 22 file_size = os.stat(file_name).st_size 23 conn.send(str(file_size).encode()) 24 ack = conn.recv(1024).decode() 25 print("确认:",ack) 26 for line in f: 27 m.update(line) 28 print("sending...") 29 conn.send(line) 30 f.close() 31 conn.send(m.hexdigest().encode()) 32 print("发送完毕") 33 server.close()
ftp_client.py
1 #!/usr/bin/env python3 2 import socket,hashlib 3 ip_address = ‘192.168.81.133‘ 4 port = 8888 5 conn_address = (ip_address,port) 6 client = socket.socket() 7 client.connect(conn_address) 8 while True: 9 cmd = input("input your cmd:> ").strip() 10 if len(cmd) == 0: 11 continue 12 if cmd.startswith("get"): 13 client.send(cmd.encode(‘utf-8‘)) 14 file_name = cmd.split()[1] 15 server_response = client.recv(1024) 16 print("收到回应:",server_response) 17 client.send("收到".encode(‘utf-8‘)) 18 total_file_size = int(server_response.decode()) 19 print("总的",total_file_size) 20 f = open(file_name + ‘.new‘,‘wb‘) 21 recov_file_size = 0 22 m = hashlib.md5() 23 while recov_file_size < total_file_size: 24 if total_file_size - recov_file_size > 1024: 25 size = 1024 26 else: 27 size = total_file_size - recov_file_size 28 print("最后收",size) 29 #print("收数据...") 30 data = client.recv(size) 31 m.update(data) 32 recov_file_size += len(data) 33 f.write(data) 34 else: 35 print("收完了,大小",recov_file_size,total_file_size) 36 f.close() 37 print("服务器端发送的原MD5",client.recv(1024).decode()) 38 print("自己算出来的最终MD5",m.hexdigest()) 39 client.close()
继承关系:
创建socket server 步骤:
下面是重写的handle:
1 import socketserver 2 class MyTCPHandler(socketserver.BaseRequestHandler): 3 def handle(self): 4 while True: 5 try: 6 self.data = self.request.recv(1024).strip() 7 print("来自",self.client_address) 8 print(self.data) 9 self.request.send(self.data.upper()) 10 except ConnectionResetError as e: 11 print("客户端退出",e) 12 break 13 if __name__ == "__main__": 14 HOST,PORT="localhost",9999 15 server = socketserver.TCPServer((HOST,PORT),MyTCPHandler) 16 server.serve_forever()
client:
1 import socket 2 client = socket.socket() #声明socket类型,同时生成socket连接对象 3 #client.connect((‘192.168.16.200‘,9999)) 4 client.connect((‘localhost‘,9999)) 5 while True: 6 msg = input(">>:").strip() 7 if len(msg) == 0:continue 8 client.send(msg.encode("utf-8")) 9 data = client.recv(10240) 10 print("recv:",data.decode()) 11 client.close()
2 使用多进程实现: (windos 下不行,不支持,但是linux 绝得好使)
2 处理单个请求,一般也用不到
3 一直收请求,直到收到一个明确的shutdown (每0.5秒检测是否给我发了shutdown 的信号)
4 告诉 server_forever() 关闭
5 地址的重用,不需要等待tcp断开
标签:
原文地址:http://www.cnblogs.com/dcc001/p/5877989.html