1、socket常见的方法
socket_常见方法_服务器端
1 import socket
2 from socket import SOL_SOCKET,SO_REUSEADDR
3 sk = socket.socket()
4
5 sk.setblocking(False)# 设置当前套接字为非阻塞状态
6 sk.settimeout(2)# 秒为单位 设置一下超时时间
7 sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
8
9 sk.bind(('127.0.0.1',8080))
10
11 sk.listen(5)
12
13 conn,addr = sk.accept()
14
15 msg = conn.recv(1024)
16
17 print('getpeername:',conn.getpeername(),addr)
18 print('getsockname:',sk.getsockname())
19 # print('getsockopt:',sk.getsockopt())
20 print(msg)
21
22 conn.close()
23 sk.close()
socket_常见方法_服务器端
socket_常见方法_客户端
1 import socket
2
3 sk = socket.socket(family=socket.AF_UNIX)
4
5 r = sk.connect_ex(('127.0.0.1', 8080))
6 print('getpeername:', sk.getpeername())
7 print('getsockname:', sk.getsockname())
8
9 sk.sendall(b'hello')
10
11 sk.close()
socket_常见方法_客户端
send()与sendall()的区别:
源码:
send()的返回值是发送的字节数量,这个数量可能小于要发送的string的字节数,也就是说可能无法发送string中所有的数据.如果有错则会抛出异常.
send方法相当于有一个自己的拆包机制,如果发送数据量大,可能会进行拆包,此时的拆包和nagle算法没有关系.
sendall()尝试发送string的所有数据,成功则返回None,失败则抛出异常.
sendall() 尝试一次都发出去,如果发不出去,就报错;发出去就返回None.
send()第一次假设发送了8个字节(hello wo),则第二次发送剩下的字节(rld\n).
2、网络编程的安全注意事项
加盐方式:
密文发送到服务器端,再进行二次加密校验;
明文发送到服务器端,然后进行加盐加密校验.
hmac模块
该模块加密是先把数据存储到字典中,然后再进行加密,方法与上述方法类似。
1 import hmac
2 hm = hmac.new(b'abc')
3 hm = hmac.new('萨芬'.encode(encoding='utf-8'),b'bads')
4 print(hm.digest())
5 print(hm.hexdigest())
6 注:加密数据时一定要指定数据编码格式
hmac模块的使用
1 import socket
2 import hashlib
3 import os
4
5 sk = socket.socket()
6
7 sk.bind(('127.0.0.1', 8080))
8
9 sk.listen(5)
10
11 conn, addr = sk.accept()
12
13 salt = b'fuck'
14 r_bytes = os.urandom(32)
15 conn.send(r_bytes)
16 md5_obj = hashlib.md5(salt)
17 md5_obj.update(r_bytes)
18 r = md5_obj.hexdigest()
19
20 client_r = conn.recv(1024).decode('utf-8')
21
22 if r == client_r:
23 print('合法的客户端,可以连接')
24 while True:
25 msg_s = input('>>>').encode('utf-8')
26 conn.send(msg_s)
27 msg_r = conn.recv(1024).decode('utf-8')
28 print(msg_r)
29 else:
30 print('不行')
31
32 conn.close()
33 sk.close()
动态加盐验证客户端的合法性_服务器端
1 import socket
2 import hashlib
3
4 sk = socket.socket()
5
6 sk.connect(('127.0.0.1', 8080))
7
8 salt = b'fuck'
9 r_bytes = sk.recv(1024)
10
11 md5_obj = hashlib.md5(salt)
12 md5_obj.update(r_bytes)
13 r = md5_obj.hexdigest()
14
15 sk.send(r.encode('utf-8'))
16
17 while True:
18 msg_r = sk.recv(1024).decode('utf-8')
19 print(msg_r)
20 msg_s = input('>>>').encode('utf-8')
21 sk.send(msg_s)
22
23 sk.close()
动态加盐验证客户端
加密方式:
登录信息以明文的方式发送至服务器端,在服务器端进行加密后,经过再次加密存储值数据库.
import socket
import hmac
import os
ADDR = ('127.0.0.1', 8080)
# 创建套接字,接收客户端的链接
def create_sk():
sk = socket.socket()
sk.bind(ADDR)
sk.listen(5)
conn, addr = sk.accept()
return conn, sk
# 和客户端通信
def com():
while 1:
msg_s = input('>>>').encode('utf-8')
conn.send(msg_s)
msg_r = conn.recv(1024).decode('utf-8')
print(msg_r)
# 验证客户端合法性
def check_client(conn):
salt = b'fuck'
r_bytes = os.urandom(32)
conn.send(r_bytes)
md5_v = hmac.new(salt, r_bytes)
r = md5_v.digest()
client_r = conn.recv(1024)
if r == client_r:
print('合法的客户端,可以连接')
com()
else:
print('不行')
return
conn, sk = create_sk()
check_client(conn)
conn.close()
sk.close()
客户端合法性校验_服务器
1 import socket
2 import hmac
3
4
5 def create_sk():
6 sk = socket.socket()
7 sk.connect(('127.0.0.1', 8080))
8 return sk
9
10
11 def md5_login(sk):
12 salt = b'fuck'
13 r_bytes = sk.recv(1024)
14 md5_v = hmac.new(salt, r_bytes)
15 r = md5_v.digest()
16 sk.send(r)
17
18
19 def com(sk):
20 while 1:
21 msg_r = sk.recv(1024).decode('utf-8')
22 print(msg_r)
23 msg_s = input('>>>').encode('utf-8')
24 sk.send(msg_s)
25
26
27 sk = create_sk()
28 md5_login(sk)
29 com(sk)
30
31 sk.close()
客户端合法性校验_客户端
3、socketserver模块
socketserver模块(这个模块封装的是并发中的技术).
1 import socketserver
2
3
4 # 并发来实现
5 class MyServer(socketserver.BaseRequestHandler):
6 def handle(self):
7 print(123)
8 self.request.send(b'abc')
9 self.request.recv(1024)
10
11
12 ser = socketserver.ThreadingTCPServer(
13 ('127.0.0.1', 8080),
14 MyServer)
15
16 ser.serve_forever()
socketserver模块的使用模板_服务器端
客户端写法未变.
1 import socket
2
3 sk = socket.socket()
4
5 sk.connect(('127.0.0.1', 8080))
6
7 print(sk.recv(b'hello'))
8
9 sk.close()
socketserver模块使用模板_客户端
具体使用:
1 import socketserver
2 import json
3 import hashlib
4 class MyServer(socketserver.BaseRequestHandler):
5 def handle(self):
6 str_dic = self.request.recv(1024).decode('utf-8')
7 dic = json.loads(str_dic)
8 md5_obj = hashlib.md5(dic['username'].encode('utf-8'))
9 md5_obj.update(dic['password'].encode('utf-8'))
10 mw_pwd = md5_obj.hexdigest()
11 with open('userinfo', encoding='utf-8') as f:
12 for line in f:
13 username, passwd = line.strip().split(':')
14 if username.strip() == dic['username'] and passwd.strip() == mw_pwd:
15 print('连接')
16 return
17 print('密码不对')
18
19 server = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyServer)
20 server.server_forever()
socketsever的的使用
1 import socket
2 import json
3
4 sk = socket.socket()
5
6 sk.connect(('127.0.0.1', 8080))
7
8 username = input('请输入用户名>>>')
9 password = input('请输入密码 >>>')
10
11 dic = {'username': username, 'password': password}
12 str_dic = json.dumps(dic)
13 sk.send(str_dic.encode('utf-8'))
序列化传输用户名info用于加密(部分)
4、浏览器中在一段时间记录用户的登录验证机制
作业:
进度条Python代码的实现:
1 import time
2 def func():
3 for i in range(1,101,1):
4 num = i // 3
5 print('\r%s%% %s>'%(i,'='*num),end='')
6 time.sleep(0.2)
7
8
9 func()
Python代码实现进度条