熟悉Python语法,重点掌握if elif语句、存在判断、列表及其方法、字符串及其方法、字典 和 文件操作等。
用到的书籍:《python基础教程》
提取码:d8yo
整个代码按照socket套接字基本编程流程编写即可:
用到的书籍:《python核心编程》
提取码:wkfj
可参考的视频:socket网络编程
实验按照题目分为“创建客户端服务端“和“实现防火墙”两步,考虑到Python语言比较简单,所以选用了Python来完成这次实验
创建客户端和服务端时必须使用socket套接字来实现,套接字就相当于网线,将两台电脑连接起来,在这里就是将客户端服务端连接起来,实现最简单的即时通讯。
客户端服务端有TCP和UDP两种,考虑到TCP比较安全稳定,数据不会丢失,所以我们选用了TCP客户端和服务器。
查阅资料得知,服务端的创建必须经过创建socket套接字、绑定IP和端口信息(bind),监听(listen)以及发送数据(send)、接收数据(recv)和关闭服务器(close)这六部分组成
而客户端则只需要创建套接字、连接服务器(connect)、发送数据、接收数据和关闭(close)这五部分组成
需要特别指出的是,每一次send发送数据,都必须有对应的recv来接收数据,而且由于输入的数据是字符串类型,而send和recv都是字节型,因此在每次发送时都必须用encode编码,接收数据时用decode解码。
这样以来,客户端和服务端就建立成功了。
在客户端服务端创建好后,就开始考虑防火墙了。
防火墙是通过对指定账户以及指定IP地址的拦截,让其无法连接到服务器,达到防火墙效果的。
我们想到在服务端定义一个禁止登陆的账户密码字典,以及一个禁止登陆的IP。
在用户用客户端连接服务器,输入账户密码时,将账户密码信息发送到服务端,服务端将接收的账户密码信息或IP地址与已经定义好的禁止登陆信息进行匹配,如果匹配成功且密码正确,将主动断开客户端的连接(close),并向其发送“该账户或IP禁止登陆”的信息,打印在屏幕上。
如果账户密码正确且未被禁止,将成功和服务器进行连接,开始进行信息交互(while True)。
这样就实现了防火墙的功能。
1、服务器
#服务端
import socket
user = {"admin": "1234"}
limitUser = {} #限制登录的用户及密码
limitIp = [] #限制登录的IP地址
#读取限制的账户密码
with open(r"limit_user.txt", "r") as f:
for line in f.readlines():
limitUser[line.split()[0]] = line.split()[1]
#读取限制的IP
with open(r"limit_ip.txt", "r") as f:
for line in f.readlines():
limitIp.append(line)
"""
# 此处为不读取文件的方式
user = {"admin": "1234"}
limitUser = {"abcd": "123", "qwer": "456", "wasd": "789"} #限制登录的用户及密码
limitIp = ["192.168.43.47"] #限制登录的IP地址
"""
host = "" #服务端IP地址
port = 20000 #服务端开放端口
bufSize = 1024 #缓存区字节大小
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建套接字
ss.bind((host, port))
ss.listen(5)
while True:
print("等待客户端连接……")
cs, addr = ss.accept()
print("已建立初步连接, 验证身份中……")
userName = cs.recv(bufSize).decode()
print("userName: ", userName)
passWord = cs.recv(bufSize).decode()
print("passWord: ", passWord)
#判断IP地址是否被限制
if addr[0] in limitIp:
print("收到限制IP的连接请求,已拒绝!")
cs.send("此IP限制登录,已断开连接".encode())
#判断账户是否被限制
elif userName in limitUser:
if limitUser[userName] == passWord:
print("收到限制用户的连接请求,已拒绝!")
cs.send("此用户限制登录,已断开连接".encode())
else:
print("密码有误,已断开连接")
cs.send("密码有误,已断开连接".encode())
#判断账户是否被允许连接
elif ((userName in user) == 0) or (user[userName] != passWord):
print("收到用户的连接请求,账户密码不匹配,已拒绝!")
cs.send("账户密码不匹配,已断开连接".encode())
else:
print("成功接收到连接,来自:", addr)
#返回身份验证成功信号
cs.send("successful".encode())
#开始进行信息交互
while True:
data = cs.recv(bufSize).decode()
if data == "exit":
break
else:
print("收到:", data)
cs.send((data.center(40, "*")).encode())
cs.close()
ss.close()
2、客户端
#客户端
import socket
#获取本机计算机名
hostname = socket.gethostname()
#根据计算机名获取本地IP
host = socket.gethostbyname(hostname)
port = 20000
bufSize = 1024
cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cs.connect((host, port)) #进行连接
userName = input("输入用户名:")
cs.send(userName.encode())
passWord = input("输入密码:")
cs.send(passWord.encode())
data = cs.recv(bufSize).decode()
if data != "successful":
print(data)
cs.close()
else:
print("成功建立稳定连接!")
while True:
data = input("输入对话信息(exit表示结束): ")
if data == "exit":
break
else:
cs.send(data.encode())
data = cs.recv(bufSize).decode()
print("收到:", data)
cs.close()
**
**