20214201 《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 2142
姓名: 刘嘉铭
学号: 20214201
实验教师:王志强
实验日期:2022年4月21日
必修/选修: 公选课
1.实验内容
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
2. 实验过程及结果
1.学习基本Socket库内容,搭建本机服务端、客户端
服务端
点击查看代码
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8001))
s.listen()
conn, address = s.accept()
data = conn.recv(1024)
print(data.decode())
conn.sendall(("服务器已经接收到了数据内容:"+str(data.decode())).encode())
s.close()
客户端
点击查看代码
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1', 8001))
str = input("请输入要传输的内容:")
s.sendall(str.encode())
data = s.recv(1024)
print(data.decode())
# print(data)
s.close()
2.学习加密、解密算法
MD5
点击查看代码
def MD5(x):
x = hashlib.md5()
x.update(str.encode("utf8"))
return x.hexdigest()
BASE64
B64Text = base64.encodebytes(SendText.encode('utf-8'))
3.程序实现
服务端
点击查看代码
import threading
import socket as sk
import time
import sys
import base64
import os
HOST = '127.0.0.1'
PORT = 8001
def socket_service():
try:
s = sk.socket(sk.AF_INET, sk.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
except sk.error as mgs:
print(mgs)
sys.exit(1)
print("Waiting For Connection......")
while True:
conn, addr = s.accept()
t = threading.Thread(target=data_deal, args=(conn, addr))
t.start()
'''while True:
data = conn.recv(1024)
# conn.sendall(data)
print(data.decode())'''
def data_deal(conn, addr):
print('Accept New Connection From {0}'.format(addr))
conn.send(("[+] Hi! Welcome to the Server!"
"[+] You can input EXIT to exit the Server"
"[+] Input F to Send a file to the Server").encode())
cont = 0
while True:
cont = cont + 1
data = conn.recv(1024)
f = open("Receive.txt","a+")
f.writelines(data.decode())
choice = f.readlines()
if cont!=1:
if choice[0]=='B64F':#!
data = conn.recv(1024)
print(data)
conn.send(("Do you want to decode? y/n").encode())
print("111")
choice = conn.recv(1024).decode()
if choice == 'y':
data = base64.decodebytes(b64data.encode('utf-8'))
conn.send(data.encode())
elif choice == 'n':
pass
else:
conn.send(("Wrong cmd").encode())
continue
print('{0} Client Sent Data is {1}'.format(addr,data.decode()))
time.sleep(1)
if data.decode() == 'EXIT' or not data:
print('{0} Client Connection is closed'.format(addr))
conn.send(("Connection is closed").encode())
break
if data.decode() =='FMD5':
print('{0} Client Send A MD5 data'.format(addr))
if data.decode() =='B64F':
print('{0} Client Send A Base64 data'.format(addr))
conn.send(bytes('Hello,{0}'.format(data),'UTF-8'))
conn.close()
if __name__ == '__main__':
socket_service()
客户端
点击查看代码
import socket as sk
import sys
import hashlib
import base64
HOST = '127.0.0.1'
PORT = 8001
def Socket_Client():
try:
s = sk.socket(sk.AF_INET, sk.SOCK_STREAM)
s.connect((HOST,PORT))
except sk.error as mgs:
print(mgs)
sys.exit(1)
print(s.recv(1024))
while 1:
cmd = input("Please input cmd:").encode()
s.send(cmd)
print('aa', s.recv(1024))
if cmd.decode() == 'EXIT':
break
if cmd.decode() == 'FMD5':
cmd = MD5Files()
s.send(cmd)
if cmd.decode() == 'B64F':
cmd = B64Files()
s.send(cmd)
s.close()
def MD5Files():
f = open("Send.txt","w+")
f.write("123456789")
f = open("Send.txt", "w+")
SendText = f.read()
MSendtext = MD5(SendText).encode()
f.close()
return MSendtext
def B64Files():
f = open("Send.txt","w+")
f.write("123456789")
f = open("Send.txt", "w+")
SendText = f.read()
B64Text = base64.encodebytes(SendText.encode('utf-8'))
f.close()
return B64Text
def MD5(x):
x = hashlib.md5()
x.update(str.encode("utf8"))
return x.hexdigest()
if __name__ == '__main__':
Socket_Client()
3. 实验过程中遇到的问题和解决过程
- 问题1:文件内容无法传输
- 问题1解决方案:权限设置不对,应使用w+和a+而不是wb
- 问题2:文件内容传输为空
- 问题2解决方案:在修改权限的基础上,明确内容的类型是byte而不是string,应传输encode的byte类型内容并在接受后decode回string类型存储。
- ...
其他(感悟、思考等)
第一次实现程序与程序之间的互动,利用socket实现的简单的数据传输令我看到了诸多可编辑的可能性,由于设想和个人水平的差距,未能完全实现,并且上述代码仍然有不完善之处,会在提交作业后进一步研究并完善,写出让自己满意的程序。