Python学习笔记-Day32-socketserver模块实现TCP协议的server与多个client端连接

内容大纲:

一、socket()里的四个参数

二、socket模块里的其他方法

三、客户端合法性验证

四、socketserver模块

一、socket()里的四个参数

sk = socket(family = AF_INET,type = SOCK_STREAM,proto = 0,fileno = None)

二、socket模块的其他方法

1、服务端套接字函数

s.bind():绑定(主机,端口号)到套接字

s.listen():开始TCP监听

s.accept():被动接受TCP客户的连接,(阻塞式)等待连接的到来

2、客户端套接字函数

s.connect():主动初始化TCP服务器连接

s.connect_ex():connect()函数的扩展版本,出错时返回错误码,而不是抛出异常

3、公共用途的套接字函数

s.recv():接收TCP数据

s.send():发送TCP数据,返回发送的字节大小,执行一次这个函数时,并不一定能发送完给定的数据,可能需要重复多次才能发送完成

s.sendall():发送完整的TCP数据,成功返回None,失败则抛出异常

s.recvfrom():接收UDP数据

s.sendto():发送UDP数据

s.getpeername():连接到当前套接字的远端的地址

s.getsockname():当前套接字的地址

s.getsockopt():返回指定套接字的参数

s.setsockopt():设置指定套接字的参数,遇到Error:Address already in use时在前面加上s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

s.close():关闭套接字

4、面向锁的套接字方法

s.setblocking():设置套接字的阻塞与非阻塞模式

  阻塞:正在运行的进程提出系统服务请求,但是因为某种原因未得到操作系统的立即相应,该进程只能调用阻塞原语把自己阻塞住,等待相应的事件出现后才被唤醒

s.settimeout():设置阻塞套接字操作的超时时间

s.gettimeout():得到阻塞套接字的超时时间

5、面向文件的套接字函数

s.fileno():套接字的文字描述符

s.makefile():创建一个与该套接字相关的文件

 三、验证客户端的合法性

背景:当使用TCP协议进行通信且不需要登录验证的时候,会有非法客户进行访问,这时可以设置客户端的合法性验证

步骤:

① server端使用os模块的urandom(n),生成一个n位的bytes类型的随机字符串

② 将该随机字符串发送给client

③ client接收随机字符串并对该字符串进行加盐的摘要,得到一个结果发送给server

④ server对随机字符用同样的盐进行摘要,并和client发送的结果进行比较

⑤ 如果结果相同就可以继续访问,结果不同就关闭conn

import os
import hmac
import socket

key = b'hello'  #
def auth(conn):
    msg = os.urandom(32)  # 随机生成一个32位的bytes类型的字符串
    conn.send(msg)  # 将随机字符串发送给client
    dig = hmac.new(key,msg)  # server对随机字符串进行摘要,得到一个对象,需要用hexdigest()才能取值
    result = conn.recv(1024) # 收到客户端的验证结果
    if dig.hexdigest()== result.decode('utf-8'):
        print('合法')
        return True
    else:
        print('不合法')
        return False

sk = socket.socket()
sk.bind(('127.0.0.1',9005))
sk.listen()
conn,addr = sk.accept()
if auth(conn):
    msg = conn.recv(1024)
    print(msg.decode('utf-8'))
else:
    conn.close()

client端:

import hmac
import socket

key = b'hello'
def auth(sk):
    msg = sk.recv(32) # 接收server发送的随机字符串
    result = hmac.new(key,msg)  
    sk.send(result.hexdigest().encode('utf-8'))

sk = socket.socket()
sk.connect(('127.0.0.1',9005))
auth(sk)
sk.send(b'welcome')
sk.close()

四、socketserver模块:实现TCP协议的多客户端访问

server端:

import  socketserver
# 用类的方式实现
class Myserver(socketserver.BaseRequestHandler):# 必须继承socketserver.BaseRequesthandler
    def handle(self):  # 必须实现handle方法
        conn = self.request
        print(conn)  # 这里的conn就是socket里的conn
        msg = conn.recv(1024)
        print(msg.decode('utf-8'))
        conn.close()
server = socketserver.ThreadingTCPServer(('127.0.0.1',9002),Myserver)  # 实例化
server.serve_forever()    # Handle one request at a time until shutdown.

client端:

# 与socket模块相同
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9002))
sk.send(b'hello')
sk.close()
原文地址:https://www.cnblogs.com/tian-tian/p/9663522.html