20191304商苏赫 实验三《Python程序设计》实验报告

学号 20191304《Python程序设计》实验三报告

  • 课程:《Python程序设计》
  • 班级: 1913
  • 姓名: 商苏赫
  • 学号:20191304
  • 实验教师:王志强
  • 实验日期:2020年5月30日
  • 必修/选修: 公选课

1.实验内容

创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。

2. 实验过程及结果

(1)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
(2)要求包含文件的基本操作,例如打开和读写操作。
(3)要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中。

运行截图如下:



运行结果里面,前三张是运行服务端在等待客户端的请求连接,两个客户端一个client1一个是client2,然后启动两个客户端,同时连接成功的结果。



服务端的代码server:

  from socket import *
  from threading import Thread
  IP = '0.0.0.0'
  PORT = 50000
  BUFLEN = 512
  #这是新线程执行的函数,每个线程负责和一个客户端进行通信
  def clientHandler(dataSocket,addr):
      while True:
          recved = dataSocket.recv(BUFLEN)
          # 当对方关闭连接的时候,返回空字符串
          if not recved:
              print(f'客户端{addr} 关闭了连接' )
              break
          # 读取的字节数据是bytes类型,需要解码为字符串
          info = recved.decode()
          print(f'收到{addr}的加密信息: {info}')

          dataSocket.send(f'服务端接收到了信息 {info}'.encode())

          def decrpt(s):
              length1 = len(s)
              length2 = len(s.replace(" ", ""))
              j = ""
              for i in range(length1):
                  if s[i] is None:
                      continue
                  if ord(s[i - 1]) == 32:
                      j = j + s[i]
                      continue
                  elif ord(s[i]) >= 33 and ord(s[i]) <= 65:
                      j = j + chr(ord(s[i]) - length2)
                      continue
                  elif ord(s[i]) > 65 and ord(s[i]) <= 126:
                      j = j + chr(ord(s[i]) + length2)
                      continue
              return j

          s = info
          descript_s = ""
          if len(s) < 6 or len(s) > 32:
              print("密码长度不符合")
          if len(s) == 0:
              print("密码不能为空")
          for i in s:
              if ord(i) < 1 and ord(i) > 127:
                  print("非法字符")
          if len(s) >= 6 and len(s) <= 32:
              descript_s = decrpt(s)
              print(f'解密后信息为: {descript_s}')

      dataSocket.close()

  # 实例化一个socket对象 用来监听客户端连接请求
  listenSocket = socket(AF_INET, SOCK_STREAM)

  # socket绑定地址和端口
  listenSocket.bind((IP, PORT))

  listenSocket.listen(8)
  print(f'服务端启动成功,在{PORT}端口等待客户端连接...')

  while True:
     # 在循环中,一直接受新的连接请求
     dataSocket, addr = listenSocket.accept()     # Establish connection with client.
     addr = str(addr)
     print(f'一个客户端 {addr} 连接成功' )

     # 创建新线程处理和这个客户端的消息收发
     th = Thread(target=clientHandler,args=(dataSocket,addr))
     th.start()

两个客户端client代码相同:

from socket import *

IP = '127.0.0.1'
SERVER_PORT = 50000
BUFLEN = 1024

# 实例化一个socket对象,指明协议
dataSocket = socket(AF_INET, SOCK_STREAM)

# 连接服务端socket
dataSocket.connect((IP, SERVER_PORT))


def encrpt(s):
    length = len(s)
    j = ""
    for i in s:
        if ord(i) <= 49:
            i = chr(ord(i) + length)
            j = j + i
        elif ord(i) > 81 and ord(i) <= 126:
            i = chr(ord(i) - length)
            j = j + i
        else:
            j = j + chr(32) + i
    return j

while True:


    s = input("请输入您想要发送的信息:")
    if  s =='exit':
        break
    enscript_s = ""
    if len(s) < 6 or len(s) > 16:
        print("长度不符合")
    if len(s) == 0:
        print("不能为空")
    for i in s:
        if ord(i) < 33 and ord(i) > 126:
            print("非法字符")

    if len(s) >= 6 and len(s) <= 16:
        enscript_s = encrpt(s)
        print(f'加密后信息为:{enscript_s}')


    # 从终端读入用户输入的字符串
    toSend = enscript_s

    # 发送消息,也要编码为 bytes
    dataSocket.send(toSend.encode())

    # 等待接收服务端的消息
    recved = dataSocket.recv(BUFLEN)
    # 如果返回空bytes,表示对方关闭了连接
    if  not recved:
        break
    # 打印读取的信息
    print(recved.decode())

dataSocket.close()

这三个运行结果,是client1和client2分别进行输入信息20191304和shiyan3然后进行加密发送给服务端,服务端进行解密得到相应结果。然后输入exit后client1和client2分别断开连接。可以看到实现了加解密,剩下的内容是读取文件进行加密发送。客户端client进行对文件test的读取并且加密发送给sever。

test中的信息如下:

运行结果如下:


其中server的代码不变,相应的client的代码改动了一些:

from socket import *

IP = '127.0.0.1'
SERVER_PORT = 50000
BUFLEN = 1024

# 实例化一个socket对象,指明协议
dataSocket = socket(AF_INET, SOCK_STREAM)

# 连接服务端socket
dataSocket.connect((IP, SERVER_PORT))


def encrpt(s):
    length = len(s)
    j = ""
    for i in s:
        if ord(i) <= 49:
            i = chr(ord(i) + length)
            j = j + i
        elif ord(i) > 81 and ord(i) <= 126:
            i = chr(ord(i) - length)
            j = j + i
        else:
            j = j + chr(32) + i
    return j

with open('test','r') as file:
    s = file.read()
print("test中信息:",s)
enscript_s = ""
if len(s) < 6 or len(s) > 16:
    print("长度不符合")
if len(s) == 0:
    print("不能为空")
for i in s:
    if ord(i) < 33 and ord(i) > 126:
        print("非法字符")

if len(s) >= 6 and len(s) <= 16:
    enscript_s = encrpt(s)
    print(f'加密后信息为:{enscript_s}')


    # 从终端读入用户输入的字符串
toSend = enscript_s

    # 发送消息,也要编码为 bytes
dataSocket.send(toSend.encode())

    # 等待接收服务端的消息
recved = dataSocket.recv(BUFLEN)

    # 打印读取的信息
print(recved.decode())
dataSocket.close()

码云链接

3. 实验过程中遇到的问题和解决过程

  • 问题1:服务端不能和多个客户端同时连接
  • 问题1解决方案:运用多线程,每个线程负责和一个客户端进行通信
  • 问题2:读取桌面文件经常出错比较复杂
  • 问题2解决方案:将所要读取的test文件和client放在一个目录下方便。

其他(感悟、思考等)

整个实验过程中还有很多问题,要求加密信息,其实上面实现的加密算法并不完善,加密一定程度上过于简单,而且没法只局限于数字和字母的加密,还没有调用更多的加密算法。还有可能完善的就是加密读取文件时,还只是txt文件,没有所有文件都可以加密和发送。还有很多有待提升的地方,不过Python的运用足够熟练,希望将来这些问题可以得到完善。

原文地址:https://www.cnblogs.com/shoudeyunkaijianyueming/p/14829261.html