zoukankan      html  css  js  c++  java
  • 项目之socket

    客户端socket

    客户端套接字完成的任务很统一,发送请求,接收请求结果
    可以封装成一个方法
    使用的tcp协议存在粘包问题,故需要自定义报头

    import json
    import struct
    
    #项目需要使用到时间,json无法序列化时间对象
    #以下操作使json将时间对象序列化
    class Myjson(json.JSONEncoder):
        def default(self, field):
            if isinstance(field, datetime):
                return field.strftime("%Y-%m-%d %X")
            return json.JSONEncoder.default(self, field)
    
    
    def send_data(c, dic):
        json_data = json.dumps(dic, cls=Myjson).encode("utf-8")
        len_data = struct.pack("i", len(json_data))
        c.send(len_data)
        c.send(json_data)
    
    
    def recv_data(c):
        struct_len = c.recv(4)
        data_len = struct.unpack("i", struct_len)[0]
        json_data = c.recv(data_len).decode("utf-8")
        dic = json.loads(json_data)
        return dic
    
    from socket import socket
    from conf.settings import CLIENT_CONF
    from lib.common import recv_data,send_data
    c = socket()
    c.connect((CLIENT_CONF["host"],CLIENT_CONF["port"]))
    
    #client 工作
    def client_run(req_dic):
        send_data(c,req_dic)
        res_dic = recv_data(c)
        return res_dic
    

    服务端socket
    与客户端的区别,需要支持并发
    使用多路复用达到并发目的
    使用select模块帮我们检测可操作连接
    recv操作是耗时的,从客户端操作系统缓存到服务端操作系统缓存,
    而send操作默认从应用程序将消息发到缓存就算完成,故是很快的
    故项目此处只检测可读连接,大型项目需检测可写连接,因为内存可能会满

    import select
    from core import user,admin
    from socket import socket
    from conf.settings import SERVER_CONF
    from lib import common
    s = socket()
    s.bind((SERVER_CONF["host"],SERVER_CONF["port"]))
    s.listen(5)
    #完成任务的分发
    def admin_interface(req_dic,c=0):
        return admin.main(req_dic,c)
    
    def user_interface(req_dic,c=0):
        return user.main(req_dic,c)
    
    func_dic={
        1:admin_interface,
        0:user_interface
    }
    
    asy_work = ["asy_upload_movie","asy_download_movie"]
    
    def client_work(r):
        req_dic = common.recv_data(r)
        if not req_dic:return
        if req_dic["user_type"] in func_dic:
            if req_dic["opt"] in asy_work:
                res_dic = func_dic[req_dic["user_type"]](req_dic,r)
            else:
                res_dic = func_dic[req_dic["user_type"]](req_dic)
        else:
            res_dic = {"status":"ng","msg":"user_type does not exist"}
        if res_dic:
            common.send_data(r,res_dic)
    #select模块
    rlist = [s,]
    def server_run():
        while True:
            rl,_,_, = select.select(rlist,[],[])
            for r in rl:
                if r == s:
                    c,_ = s.accept()
                    rlist.append(c)
                else:
                    try:
                        client_work(r)
                    except ConnectionResetError:
                        r.close()
                        rlist.remove(r)
    
  • 相关阅读:
    38. Count and Say(C++)
    35. Search Insert Position(C++)
    29. Divide Two Integers(C++)
    c++读取utf-8格式中英文混合string
    一种局部二值化算法:Sauvola算法
    Ubuntu 1804 本地显示远程服务器文件
    caffe 预训练 或者Fine-Tuning 操作
    caffe/blob.hpp:9:34: fatal error: caffe/proto/caffe.pb.h: 没有那个文件或目录
    转载---LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
    [leetcode-921-Minimum Add to Make Parentheses Valid]
  • 原文地址:https://www.cnblogs.com/robert-zhou/p/10426710.html
Copyright © 2011-2022 走看看