# Python Socket 实现一个简单的用户认证系统 这次写的是一个简单的用户认证系统。 整体思路是 1. 服务端负责保存和校验用户名、密码 2. 客户端负责输入用户名、密码 3. 客户端把用户输入的数据发送给服务端 4. 服务端判断用户名和密码是否正确 5. 服务端把登录结果返回给客户端 这个案例主要用到了三个知识点 python socket json 文件读取一、项目结构这个用户认证系统里面主要有三个文件用户认证系统 ├── client.py ├── server.py └── 用户名和密码.txt其中client.py是客户端代码负责让用户输入用户名和密码。server.py是服务端代码负责接收客户端发来的数据并进行认证。用户名和密码.txt是保存用户名和密码的文件。文件内容是zcx123456也就是说目前系统中有一个用户用户名zcx 密码123456二、服务端代码服务端代码如下importsocketimportjson serversocket.socket(socket.AF_INET,socket.SOCK_STREAM)server.bind((127.0.0.1,8001))server.listen(5)whileTrue:conn,addrserver.accept()print(有客户端来连接了)conn.sendall(欢迎使用用户认证系统.encode(utf-8))whileTrue:dataconn.recv(1024)ifdata.encode(utf-8):breakuser_dictjson.loads(data.decode(utf-8))user_nameuser_dict[username]user_passworduser_dict[password]foundFalseauthenticatedFalsewithopen(用户名和密码.txt,r,encodingutf-8)asf:forlineinf:lineline.strip()ifnotline:continuefile_username,file_passwordline.split( )iffile_usernameuser_name:foundTrueiffile_passworduser_password:authenticatedTruebreakiffoundandauthenticated:conn.sendall(登录成功.encode(utf-8))breakeliffoundandnotauthenticated:conn.sendall(密码错误.encode(utf-8))else:conn.sendall(用户名不存在.encode(utf-8))conn.close()三、创建 socket 服务端首先创建一个 socket 对象serversocket.socket(socket.AF_INET,socket.SOCK_STREAM)这里的socket.AF_INET表示使用 IPv4 地址。socket.SOCK_STREAM表示使用 TCP 协议。TCP 是一种可靠连接客户端和服务端建立连接之后就可以互相发送数据。四、绑定地址和端口服务端需要绑定 IP 和端口server.bind((127.0.0.1,8001))这里的127.0.0.1表示本机地址。8001表示端口号。也就是说这个服务端运行在本机的8001端口上。然后开始监听server.listen(5)表示服务端开始等待客户端连接。五、等待客户端连接服务端通过下面这句代码等待客户端连接conn,addrserver.accept()当客户端连接成功后accept()会返回两个值conn表示客户端和服务端之间的连接对象。addr表示客户端的地址信息。连接成功之后服务端会打印有客户端来连接了然后给客户端发送欢迎信息conn.sendall(欢迎使用用户认证系统.encode(utf-8))因为网络传输的数据必须是字节类型所以字符串需要先进行编码encode(utf-8)六、接收客户端发来的数据服务端使用下面这句代码接收客户端数据dataconn.recv(1024)这里的1024表示一次最多接收 1024 个字节。客户端发来的数据是 JSON 字符串所以服务端需要先解码data.decode(utf-8)然后再用json.loads()转成 Python 字典user_dictjson.loads(data.decode(utf-8))客户端发送的数据格式大概是这样{username:zcx,password:123456}所以服务端可以这样取出用户名和密码user_nameuser_dict[username]user_passworduser_dict[password]七、读取用户名和密码文件服务端会打开保存用户名和密码的文件withopen(用户名和密码.txt,r,encodingutf-8)asf:然后一行一行读取forlineinf:每一行的数据格式是用户名 密码比如zcx123456所以可以使用空格分割file_username,file_passwordline.split( )这样就可以拿到文件中的用户名和密码。八、判断用户名和密码是否正确代码中定义了两个变量foundFalseauthenticatedFalsefound表示是否找到了这个用户名。authenticated表示密码是否认证成功。判断逻辑是iffile_usernameuser_name:foundTrueiffile_passworduser_password:authenticatedTruebreak如果用户名匹配就把found改成True。如果密码也匹配就把authenticated改成True。九、返回登录结果最后根据判断结果服务端会返回不同的信息。如果用户名存在并且密码正确conn.sendall(登录成功.encode(utf-8))如果用户名存在但是密码错误conn.sendall(密码错误.encode(utf-8))如果用户名不存在conn.sendall(用户名不存在.encode(utf-8))这样客户端就可以根据服务端返回的结果知道登录是否成功。十、客户端代码客户端代码如下importsocketimportjson clientsocket.socket(socket.AF_INET,socket.SOCK_STREAM)client.connect((127.0.0.1,8001))messageclient.recv(1024)print(message.decode(utf-8))whileTrue:usernameinput(请输入你的用户名(Q退出))ifusernameQ:breakpasswordinput(请输入你的密码(Q退出))ifpasswordQ:breakuser_data{username:username,password:password}client.sendall(json.dumps(user_data,ensure_asciiFalse).encode(utf-8))log_messageclient.recv(1024)iflog_message.decode(utf-8)登录成功:print(log_message.decode(utf-8))breakelse:print(log_message.decode(utf-8)请重新输入(Q退出))十一、客户端连接服务端客户端同样先创建 socket 对象clientsocket.socket(socket.AF_INET,socket.SOCK_STREAM)然后连接服务端client.connect((127.0.0.1,8001))这里连接的是本机的8001端口。所以运行程序时必须先运行服务端server.py再运行客户端client.py。连接成功之后客户端会先接收服务端发来的欢迎信息messageclient.recv(1024)print(message.decode(utf-8))输出结果是欢迎使用用户认证系统十二、输入用户名和密码客户端通过input()获取用户输入usernameinput(请输入你的用户名(Q退出))如果用户输入Q就退出程序ifusernameQ:break密码也是一样passwordinput(请输入你的密码(Q退出))然后把用户名和密码放到一个字典中user_data{username:username,password:password}十三、使用 JSON 发送数据字典不能直接通过 socket 发送所以需要先转成 JSON 字符串json.dumps(user_data,ensure_asciiFalse)然后再编码成字节.encode(utf-8)完整发送代码是client.sendall(json.dumps(user_data,ensure_asciiFalse).encode(utf-8))这里的ensure_asciiFalse是为了让中文能够正常显示不会被转义成 Unicode 编码。十四、接收登录结果客户端发送用户名和密码之后会等待服务端返回结果log_messageclient.recv(1024)然后判断是否登录成功iflog_message.decode(utf-8)登录成功:print(log_message.decode(utf-8))breakelse:print(log_message.decode(utf-8)请重新输入(Q退出))如果服务端返回登录成功客户端打印结果并退出循环。如果返回密码错误或者用户名不存在客户端会提示重新输入。十五、运行流程运行时需要先启动服务端python server.py然后再启动客户端python client.py客户端显示欢迎使用用户认证系统 请输入你的用户名(Q退出)如果输入zcx再输入密码123456服务端验证通过客户端输出登录成功如果用户名正确但是密码错误就会输出密码错误请重新输入(Q退出)如果用户名不存在就会输出用户名不存在请重新输入(Q退出)十六、总结这个用户认证系统虽然比较简单但是已经包含了一个客户端和服务端通信的基本流程。它主要实现了这些功能服务端监听端口等待客户端连接客户端连接服务端客户端输入用户名和密码使用 JSON 格式发送用户数据服务端读取本地文件中的用户名和密码服务端判断用户是否存在、密码是否正确服务端把登录结果返回给客户端这个案例可以帮助我们理解socket是如何完成网络通信的。json是如何在客户端和服务端之间传递结构化数据的。文件读取是如何用来保存和查询用户信息的。简单来说这个项目就是客户端输入账号密码 ↓ 通过 socket 发送给服务端 ↓ 服务端读取文件进行校验 ↓ 把登录结果返回给客户端这就是一个最基础版本的 Python 用户认证系统。