Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信
Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信
目录
1. 操作系统的缓冲区
-
缓存区
1.为什么存在缓冲区? 暂时存储一些数据. 缓冲区存在如果网络波动,保证数据的收发稳定,匀速. 2.缺点: 造成了粘包现象之一.
2. 基于TCP协议的socket循环通信
-
服务端(server)
import socket server = socket.socket() server.bind(('127.0.0.1',8848)) server.listen() # listen: 允许5个人链接我,剩下的链接也可以链接,等待. conn,addr = server.accept() # 等待客户端连接,阻塞状态中 print(f'链接来了: {conn,addr}') while 1: try: # 等待接收客户端消息 from_client_data = conn.recv(1024) # 最多接受1024字节 # 客户端输入Q表示客户端正常退出 if from_client_data.upper() == b'Q': print('客户端正常退出聊天了') break # 打印客户端的IP以及发送过来的消息 print(f'来自客户端{addr}消息:{from_client_data.decode("utf-8")}') # 给客户端返回消息 to_client_data = input('>>>').strip().encode('utf-8') conn.send(to_client_data) except ConnectionResetError: print('客户端链接中断了') break conn.close() server.close()
-
客户端(client)
import socket client = socket.socket() client.connect(('127.0.0.1',8848)) while 1: to_server_data = input('>>>输入q或者Q退出').strip().encode('utf-8') # 服务端如果接受到了空的内容,服务端就会一直阻塞中,所以无论哪一端发送内容时,都不能为空发送 if not to_server_data: print('发送内容不能为空') continue client.send(to_server_data) # 输入Q表示客户端正常退出 if to_server_data.upper() == b'Q': break # 接收服务端返回的消息 from_server_data = client.recv(1024) # 最多接受1024字节 print(f'来自服务端消息:{from_server_data.decode("utf-8")}') client.close()
3. 基于TCP协议的socket链接+循环 通信
-
服务端(server)
import socket server = socket.socket() server.bind(('127.0.0.1',8848)) # 必须是元组 server.listen(2) while 1: conn,addr = server.accept() # 等待客户端连接,阻塞状态中 print(f'链接来了: {conn,addr}') while 1: try: from_client_data = conn.recv(1024) # 最多接受1024字节 if from_client_data.upper() == b'Q': print('客户端正常退出聊天了') break print(f'来自客户端{addr}消息:{from_client_data.decode("utf-8")}') to_client_data = input('>>>').strip().encode('utf-8') conn.send(to_client_data) except ConnectionResetError: print('客户端链接中断了') break conn.close() server.close()
-
客户端(client)
import socket client = socket.socket() client.connect(('127.0.0.1',8848)) while 1: to_server_data = input('>>>输入q或者Q退出').strip().encode('utf-8') if not to_server_data: print('发送内容不能为空') continue client.send(to_server_data) if to_server_data.upper() == b'Q': break from_server_data = client.recv(1024) # 最多接受1024字节 print(f'来自服务端消息:{from_server_data.decode("utf-8")}') client.close()
4. 基于TCP协议的socket应用实例:执行远程命令
-
服务端(server)
import socket import subprocess server = socket.socket() server.bind(('127.0.0.1',8848)) server.listen(2) while 1: conn,addr = server.accept() # 等待客户端链接我,阻塞状态中 print(f'链接来了: {conn,addr}') while 1: try: from_client_data = conn.recv(1024) # 最多接受1024字节 if from_client_data.upper() == b'Q': print('客户端正常退出聊天了') break # 执行远程命令 obj = subprocess.Popen(from_client_data.decode('utf-8'), shell=True, # 执行正确指令的管道 stdout=subprocess.PIPE, # 执行错误指令的管道 stderr=subprocess.PIPE, ) # 将正确指令以及错误指令得到的结果返回给客户端 result = obj.stdout.read() + obj.stderr.read() conn.send(result) except ConnectionResetError: print('客户端链接中断了') break conn.close() server.close() # shell: 命令解释器,相当于调用cmd 执行指定的命令。 # stdout:正确结果丢到管道中。 # stderr:错了丢到另一个管道中。 # windows操作系统的默认编码是gbk编码。
-
客户端(client)
import socket client = socket.socket() client.connect(('127.0.0.1',8848)) while 1: to_server_data = input('>>>输入q或者Q退出').strip().encode('utf-8') if not to_server_data: print('发送内容不能为空') continue client.send(to_server_data) if to_server_data.upper() == b'Q': break from_server_data = client.recv(1024) # 最多接受1024字节 print(f'{from_server_data.decode("gbk")}') client.close()
5. socketserver通信
-
server服务端
import socketserver class Myserver(socketserver.BaseRequestHandler): def handle(self): while 1: from_client_msg = self.request.recv(1024).decode('utf-8') print(f'来自客户端{self.client_address}的消息:',from_client_msg) to_client_msg = input('>>>') self.request.send(to_client_msg.encode('utf-8')) if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),Myserver) server.serve_forever()
-
client客户端
import socket client = socket.socket() client.connect(('127.0.0.1',8888)) while 1: to_server_msg = input('>>>').encode('utf-8') client.send(to_server_msg) from_server_msg = client.recv(1024) print('来自服务端的消息:',from_server_msg.decode('utf-8')) client.close()