Python课程设计 第 35 / 52 篇

套接服务-参考答案

  1. 基于TCP协议写一个远程执行命令的程序,要求不能产生任何粘包,recv参数设置成512

服务端

from socket import *
import subprocess
import struct

server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)

while True:
    conn, client_addr = server.accept()  # (连接对象,客户端的ip和端口)
    print(client_addr)
    while True:
        try:
            cmd = conn.recv(1024)
            obj = subprocess.Popen(cmd.decode('utf-8'),
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE
                                   )
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()

            # 1、制作固定长度的报头
            total_size = len(stdout) + len(stderr)
            header = struct.pack('i', total_size)

            # 2、发送报头
            conn.send(header)

            # 3、发送真实的数据
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break

    conn.close()
server.close()

客户端

from socket import *
import struct

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))

while True:
    cmd = input('>>>: ').strip()
    if not cmd: continue
    client.send(cmd.encode('utf-8'))
    # 1、先收固定长度的报头
    header = client.recv(4)
    # 2、解析报头
    total_size = struct.unpack('i', header)[0]
    print(total_size)  # 1025
    # 3、根据报头内的信息,收取真实的数据

    recv_size = 0
    res = b''
    while recv_size < total_size:
        recv_data = client.recv(1024)
        res += recv_data
        recv_size += len(recv_data)

    print(res.decode('utf-8'))
client.close()
  1. 基于UDP写一个qq聊天程序,双方可随时推出聊天程序,服务器记录聊天内容

服务端

import socket

server_address = ('127.0.0.1', 8082)
client1_address = ('127.0.0.1', 8083)
client2_address = ('127.0.0.1', 8085)

udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_server.bind(('127.0.0.1', 8082))

while True:
    msg, address = udp_server.recvfrom(512)
    if msg == b'q':
        msg_server = '来自[%s:%s]已中断聊天:%s' % (address[0], address[1], msg.decode('utf-8'))
        print(msg_server)
        udp_server.sendto(msg, client1_address)
        udp_server.sendto(msg, client2_address)
    msg_server = '来自[%s:%s]的一条消息:%s' % (address[0], address[1], msg.decode('utf-8'))
    print(msg_server)
    msg = '收到消息:【 %s 】' % msg.decode('utf-8')
    if address == client1_address:
        udp_server.sendto(msg.encode('utf-8'), client2_address)

    elif address == client2_address:
        udp_server.sendto(msg.encode('utf-8'), client1_address)

客户端

import socket

server_address = ('127.0.0.1', 8082)
client1_address = ('127.0.0.1', 8083)
client2_address = ('127.0.0.1', 8085)

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.bind(client1_address)

def receive_msg():
    while True:
        try:
            msg, address = client.recvfrom(512)
            if msg.decode('utf-8') == 'q': break
            print(msg.decode('utf-8'))
            msg = input('发送消息>>:').strip()
            client.sendto(msg.encode('utf-8'), address)
        except Exception:
            break

    client.close()

def send_msg():
    while True:
        try:
            msg = input('发送信息>>:').strip()
            client.sendto(msg.encode('utf-8'), server_address)
            msg, address = client.recvfrom(512)
            if msg.decode('utf-8') == 'q': break
            if not address == client1_address:
                print(msg.decode('utf-8'))
            send_msg()
        except Exception:
            break

    client.close()

func_dict = {
    '1': receive_msg,
    '2': send_msg
}

while True:
    print("""
    1 接收消息
    2 发送消息
    """)
    choice = input('请选择要进入的状态>>:').strip()
    if choice not in func_dict: continue
    func_dict[choice]()
  1. 基于UDP协议写一个NTP程序(几台机器同步时间的程序)

服务端

import socket
import time

server_address = ('127.0.0.1', 8080)

udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_server.bind(server_address)

while True:
    # 获取当前时间
    now_time = time.strftime('%Y-%m-%d %H:%M:%S %p')
    msg, address = udp_server.recvfrom(512)
    udp_server.sendto(now_time.encode('utf-8'), address)

客户端

import socket
import time

server_address = ('127.0.0.1', 8080)

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
    time.sleep(5)
    msg = 'now time'
    client.sendto(msg.encode('utf-8'), server_address)
    res, server_address = client.recvfrom(512)
    print(res.decode('utf-8'))