原则:发送一个接受一个
原理:发送执行命令的大小给客户端,客户端根据接受的大小判断是否全部接收了服务器sendall()发送的全部
利用send发送的全部数据都是bytes类型的,需要进行字符编码的转换,因为中文环境,所以需要转换GBK查看
客户端:
# 客户端 import socket # family=AF_INET, 代表使用IPV4的IP协议 # type=SOCK_STREAM 代表使用TCP协议进行连接 client = socket.socket() ip_addr = (‘127.0.0.1‘, 9999) try: client.connect(ip_addr) exit_flag = True while exit_flag: # 发送一定要有接收 inp = input(‘>>>:‘) if inp != ‘bye‘: client.send(bytes(inp, ‘utf-8‘)) exit_flag = True else: client.send(bytes(inp, ‘utf-8‘)) exit_flag = False result_len = int(str(client.recv(1024), encoding=‘utf-8‘)) # 接受服务器端发送的数据大小 print(‘客户端接收的大小为:‘, result_len) data_size = bytes() while len(data_size) != result_len: info = client.recv(1024) # 最大接收1024K数据,# 传送/接收的数据一定是byte类型 data_size += info print(‘客户端:‘, str(data_size, ‘gbk‘)) # Win7系统就是GBK编码返回的数据 except Exception as e: print(‘客户端关闭连接‘, e) finally: client.close()
服务端:
# 服务端 import socket import subprocess # family=AF_INET, 代表使用IPV4的IP协议 # type=SOCK_STREAM 代表使用TCP协议进行连接 server = socket.socket() # 创建socket ip_addr = (‘127.0.0.1‘, 9999) # 1024之前的端口,默认是OS使用 server.bind(ip_addr) # 要求必须是一个元组 server.listen(3) # 开始监听传入连接。在拒绝连接之前,可以挂起的最大连接数量。 while True: conn, addr = server.accept() # 接受连接并返回(conn,address) # 其中conn是新的套接字对象[客户端],可以用来接收和发送数据。 # address是连接客户端的地址。 exit_flag = True while exit_flag: print(‘当前连接对象‘, addr) # 发送一定要有接收 data = conn.recv(1024) print(‘服务器:‘, str(data, ‘utf-8‘)) obj = subprocess.Popen(str(data, ‘utf-8‘), shell=True, stdout=subprocess.PIPE) cmd_result = obj.stdout.read() # 编码用GBK,默认在当前文件所在的文件路径 conn.sendall(bytes(str(len(cmd_result)), encoding=‘utf-8‘)) # 发送数据大小,int不能直接转换为bytes print(‘服务器发送的大小为:‘, len(cmd_result)) # 某种程度上解决了粘包现象 conn.sendall(cmd_result) # 发送全部的数据 server.close()
注意: 粘包现象: 在服务器端连续send()的时候,2个send直接会等待很短的时间,所以导致传递过去的len会报错,因为不能转换为int型,可以利用Time.sleep解决,也可以遵循一收一发的原则,发送一个以后在发送一次解决。
原文地址:https://www.cnblogs.com/ftl1012/p/9383739.html
时间: 2024-11-07 23:37:22