码迷,mamicode.com
首页 > 其他好文 > 详细

验证客户端链接以及socketserver模块

时间:2018-09-17 19:44:22      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:NPU   wan   rev   接收   col   服务端   put   threading   and   

技术分享图片
 1 服务端套接字函数
 2 s.bind()    绑定(主机,端口号)到套接字
 3 s.listen()  开始TCP监听
 4 s.accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来
 5 
 6 客户端套接字函数
 7 s.connect()     主动初始化TCP服务器连接
 8 s.connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
 9 
10 公共用途的套接字函数
11 s.recv()            接收TCP数据
12 s.send()            发送TCP数据
13 s.sendall()         发送TCP数据
14 s.recvfrom()        接收UDP数据
15 s.sendto()          发送UDP数据
16 s.getpeername()     连接到当前套接字的远端的地址
17 s.getsockname()     当前套接字的地址
18 s.getsockopt()      返回指定套接字的参数
19 s.setsockopt()      设置指定套接字的参数
20 s.close()           关闭套接字
21 
22 面向锁的套接字方法
23 s.setblocking()     设置套接字的阻塞与非阻塞模式
24 s.settimeout()      设置阻塞套接字操作的超时时间
25 s.gettimeout()      得到阻塞套接字操作的超时时间
26 
27 面向文件的套接字的函数
28 s.fileno()          套接字的文件描述符
29 s.makefile()        创建一个与该套接字相关的文件
socket的更多用法介绍

验证客户端连接的合法性

端口的范围:0-65535

技术分享图片
 1 #server
 2 import os
 3 import socket
 4 import hmac
 5 def auth(conn):
 6     msg = os.urandom(32)    #生成一个随机字符串
 7     conn.send(msg)              #发送到client端
 8     result = hmac.new(secret_key, msg) #处理这个字符串,得到一个结果
 9     client_digest = conn.recv(1024)      #接收client端处理的结果
10     if result.hexdigest() == client_digest.decode(utf-8):
11         print(合法的连接)    #对比成功可以继续通信
12         return True
13     else:
14         print(不合法的连接)    #不成功  close
15         return False
16 secret_key = bwangwang
17 sk = socket.socket()
18 sk.bind((127.0.0.1, 8520))
19 sk.listen()
20 conn, addr = sk.accept()
21 if auth(conn):
22     print(conn.recv(1024))  #可以正常与client端进行通信了
23     conn.close()
24 else:
25     conn.close()
26 sk.close()
27 
28 #client
29 import hmac
30 import socket
31 def auth(sk):
32     msg = sk.recv(32)
33     result = hmac.new(key, msg)
34     res = result.hexdigest()
35     sk.send(res.encode(utf-8))
36 key =bwangwang
37 sk = socket.socket()
38 sk.connect((127.0.0.1, 8520))
39 auth(sk)
40 sk.send(bupload)    #正常的和server端进行通信
41 sk.close()
验证

主要用于内部的验证,对登陆者进行简单的验证

socketserver 模块

TCP协议下,server端可以与多个client端连接

技术分享图片
 1 #server端
 2 import socketserver
 3 #tcp协议的server端不需要导入socket
 4 class Myserver(socketserver.BaseRequestHandler):
 5     def handle(self):
 6         conn = self.request
 7         while True:
 8             msg = input(>>>)
 9             conn.send(msg.encode(utf-8))
10             re_msg = conn.recv(1024)
11             print(re_msg.decode(utf-8))
12 
13 socketserver.TCPServer.allow_reuse_address = True
14 # 设置allow_reuse_address允许服务器重用地址
15 server = socketserver.ThreadingTCPServer((127.0.0.1, 8520),Myserver)
16 # 创建一个server, 将服务地址绑定到127.0.0.1:8520
17 server.serve_forever()
18 # 让server永远运行下去,除非强制停止程序
19 
20 #client
21 import socket
22 sk = socket.socket()
23 sk.connect((127.0.0.1, 8520))
24 while True:
25     ret = sk.recv(1024)
26     print(ret.decode(utf-8))
27     msg = input(>>>)
28     sk.send(msg.encode(utf-8))
29     if msg == q:
30         break
31 sk.close()
sockterserver

 

 

 

########################################################

基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环

socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)

server类:

技术分享图片

request类:

技术分享图片

继承关系:

技术分享图片

技术分享图片

 

 技术分享图片

 

以下述代码为例,分析socketserver源码:

ftpserver=socketserver.ThreadingTCPServer((‘127.0.0.1‘,8080),FtpServer)
ftpserver.serve_forever()

查找属性的顺序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServer

  1. 实例化得到ftpserver,先找类ThreadingTCPServer的__init__,在TCPServer中找到,进而执行server_bind,server_active
  2. 找ftpserver下的serve_forever,在BaseServer中找到,进而执行self._handle_request_noblock(),该方法同样是在BaseServer中
  3. 执行self._handle_request_noblock()进而执行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),然后执行self.process_request(request, client_address)
  4. 在ThreadingMixIn中找到process_request,开启多线程应对并发,进而执行process_request_thread,执行self.finish_request(request, client_address)
  5. 上述四部分完成了链接循环,本部分开始进入处理通讯部分,在BaseServer中找到finish_request,触发我们自己定义的类的实例化,去找__init__方法,而我们自己定义的类没有该方法,则去它的父类也就是BaseRequestHandler中找....

源码分析总结:

基于tcp的socketserver我们自己定义的类中的

  1.   self.server即套接字对象
  2.   self.request即一个链接
  3.   self.client_address即客户端地址

基于udp的socketserver我们自己定义的类中的

  1.   self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象),如(b‘adsf‘, <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=(‘127.0.0.1‘, 8080)>)
  2.   self.client_address即客户端地址

验证客户端链接以及socketserver模块

标签:NPU   wan   rev   接收   col   服务端   put   threading   and   

原文地址:https://www.cnblogs.com/zhigu/p/9663489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!