Python Socket编程并验证身份

前段时间太忙了,不仅有考试还要准备一个比赛的决赛,哎比赛没有取得很好的成绩说多了都伤心,已经很长时间没有写博客了。上个星期一个课程的老师布置了关于Socket编程的作业,虽然写python有一段时间了,但是没有写过网络编程相关的代码,很值得记录下来。

另外,这是我用Java写的一份,地址,在Java中我就没用数据库了,直接用键值对的形式保存的user信息。

要求

那个老师很奇怪,实验要求上写了在服务器端要用数据库,但是又告诉我们通信不用数据库,但是我还是加上了连接数据库的代码。

环境

  • python3
  • 库:socket,pymysql,time

代码

服务器端:server_z.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# -*- coding: utf-8 -*-
__author__ = 'buzz'
__date__ = '2017/11/27 下午1:26'
import socket
import threading
import time
import pymysql
# mysql connection
db = pymysql.connect("127.0.0.1", "root", "XXXX", "sockettest")
cursor = db.cursor()
def tcplink(ss, addr):
print('...connection from' + str(addr))
ss.send('Welcome! '.encode())
while True:
ss.send('please input the username and password to login(input "exit" to quit) '.encode())
time.sleep(1)
ss.send('username: '.encode())
data = ss.recv(1024).decode()
cursor.execute('select username from people;')
d1 = cursor.fetchall()
if data == 'exit' or not data:
break
if data in d1[0][0]:
time.sleep(1)
ss.send('password: '.encode())
data_pwd = ss.recv(1024).decode()
sql = "select password from `people` where username='{}';".format(data)
cursor.execute(sql)
pwd = cursor.fetchall()
if pwd[0][0] == data_pwd:
time.sleep(1)
ss.send('Success! '.encode())
time.sleep(1)
last = 'byebye! ' + data
ss.send(last.encode())
break
else:
time.sleep(1)
ss.send('Sign in failed! password wrong!'.encode())
else:
time.sleep(1)
ss.send('Sign in failed! User is not exist!'.encode())
ss.close()
print('Connection from {} closed.'.format(addr))
address = ('127.0.0.1', 31501)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(address)
s.listen(5)
print('Waiting for connection...')
while True:
ss, addr = s.accept()
t = threading.Thread(target=tcplink, args=(ss, addr))
t.start()

客户端:client_z.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# -*- coding: utf-8 -*-
__author__ = 'buzz'
__date__ = '2017/11/27 下午1:26'
import socket, time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 31501))
print(s.recv(1024).decode())
while True:
print(s.recv(1024).decode())
d1 = s.recv(1024).decode()
if 'username:' in d1:
user = input("username---> ")
s.send(user.encode())
d2 = s.recv(1024).decode()
if 'password: ' == d2:
pwd = input("password---> ")
s.send(pwd.encode())
d3 = s.recv(1024).decode()
print(d3)
d4 = s.recv(1024).decode()
print(d4)
break
if 'failed' in d3:
break
else:
print(d2)
s.close()

解释

需要注意的有:

  • 发过去的信息要进行编码,收到的消息要进行解码,比如这样:s.send('haha'.encode())s.recv(1024).decode()
  • 有时候需要设置 time.sleep(1),让进程缓一缓不要太快了

结果