Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信

目录

  • Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信
  • 1. 操作系统的缓冲区
  • 2. 基于TCP协议的socket循环通信
  • 服务端(server)
  • 客户端(client)
  • 3. 基于TCP协议的socket链接+循环 通信
  • 服务端(server)
  • 客户端(client)
  • 4. 基于TCP协议的socket应用实例:执行远程命令
  • 服务端(server)
  • 客户端(client)
  • 5. socketserver通信
  • server服务端
  • client客户端

1. 操作系统的缓冲区

  • 缓存区
1.为什么存在缓冲区?
  暂时存储一些数据.
  缓冲区存在如果网络波动,保证数据的收发稳定,匀速.
2.缺点: 造成了粘包现象之一.

python socket 清空接收缓冲区 python的socket缓冲区_客户端

python socket 清空接收缓冲区 python的socket缓冲区_服务端_02

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()