一、基于tcp通信的套接字程序
服务端:
from socket import * # 服务端必须满足至少三点: # 1.绑定一个固定的ip和port # 2.一直对外提供服务,稳定运行 # 3.能够支持并发 server = socket(AF_INET, SOCK_STREAM) server.bind(('127.0.0.1', 9555)) server.listen(5) client, addr = server.accept() data = client.recv(1024) print(data.decode('utf-8')) client.send(data.upper()) client.close() server.close()
客户端:
from socket import * client = socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',9555)) msg = input('>>>:').strip() client.send(msg.encode('utf-8')) data = client.recv(1024) print(data) client.close()
二、修改bug + 通信循环 + 连接循环
上述存在客户端退出时服务端即会崩溃的bug,而且无法实现用户的多次输入,以及服务端无法一直对外服务的问题,对此进行修改
服务端:
from socket import * server = socket(AF_INET, SOCK_STREAM) server.bind(('127.0.0.1', 8081)) server.listen(5) # 链接循环 while True: conn, client_addr = server.accept() print(client_addr) # 通信循环 while True: try: data = conn.recv(1024) if len(data) == 0: break # 针对linux系统 print('-->收到客户端的消息: ', data) conn.send(data.upper()) except ConnectionResetError: break conn.close() server.close()
客户端:
from socket import * client = socket(AF_INET, SOCK_STREAM) client.connect(('127.0.0.1', 8081)) # 通信循环 while True: msg=input('>>: ').strip() #msg='' if len(msg) == 0:continue client.send(msg.encode('utf-8')) #client.send(b'') # print('has send') data=client.recv(1024) # print('has recv') print(data) client.close()
三、粘包问题解决方案
服务端:
import socket import subprocess import struct import json IP = '127.0.0.1' PORT = 8383 ADDRESS = (IP, PORT) BUFSIZE = 1024 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(ADDRESS) server.listen(5) tag = True while tag: conn, addr = server.accept() while tag: try: data = conn.recv(BUFSIZE) if not data: print('服务端断开。。。。') break # 获取sub对象 res = subprocess.Popen(data.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print('>>>>', data.decode('utf-8')) # 成功的结果 stdout = res.stdout.read() # 失败的结果 stderr = res.stderr.read() # 1.制作报头 header_dic = { 'filename': 'a.txt', 'md5': 'sd7a86d87sad6as', 'total_size': len(stdout) + len(stderr) } header_json = json.dumps(header_dic) header_bytes = header_json.encode('utf-8') # 2.先发送报头长度 conn.send(struct.pack('i', len(header_bytes))) # 3.再发送报头 conn.send(header_bytes) # 4.最后发送数据 conn.send(stdout) conn.send(stderr) except ConnectionResetError: break conn.close() server.close()
客户端:
import socket import struct import json IP = '127.0.0.1' PORT = 8383 ADDRESS = (IP, PORT) BUFSIZE = 1024 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(ADDRESS) while True: msg = input('>>>') if len(msg) == 0: continue client.send(msg.encode('utf-8')) # 1.先获取报头长度 header_size = struct.unpack('i',client.recv(4))[0] #2.在获取报头 header_bytes=client.recv(header_size) header_json=header_bytes.decode('utf-8') header_dic=json.loads(header_json) print(header_json) total_size=header_dic['total_size'] # 3.在获取真正数据 cmd_res=b'' recv_size=0 while recv_size<total_size: data=client.recv(1024) recv_size+=len(data) cmd_res+=data print(cmd_res.decode('gbk')) client.close()
四、远程控制
服务端:
from socket import * import subprocess # 服务器必须满足至少三点 # 1. 绑定一个固定的ip和port # 2. 一直对外提供服务,稳定运行 # 3. 能够支持并发 server = socket(AF_INET, SOCK_STREAM) server.bind(('192.168.13.235', 8080)) server.listen(5) # 链接循环 while True: conn, client_addr = server.accept() # 通信循环 while True: # 捕捉异常防止客户端断开链接导致服务器报错 try: data = conn.recv(1024) obj = subprocess.Popen(data.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout = obj.stdout.read() stderr = obj.stderr.read() conn.send(stdout) except ConnectionResetError: break conn.close() server.close()
客户端:
from socket import * import subprocess # 服务器必须满足至少三点 # 1. 绑定一个固定的ip和port # 2. 一直对外提供服务,稳定运行 # 3. 能够支持并发 server = socket(AF_INET, SOCK_STREAM) server.bind(('192.168.13.235', 8080)) server.listen(5) # 链接循环 while True: conn, client_addr = server.accept() # 通信循环 while True: # 捕捉异常防止客户端断开链接导致服务器报错 try: data = conn.recv(1024) obj = subprocess.Popen(data.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout = obj.stdout.read() stderr = obj.stderr.read() conn.send(stdout) except ConnectionResetError: break conn.close() server.close()