软件服务器(附客户端SDK)

一、server

# 应用软件服务器端(附客户端访问sdk)
# 1、数据传输分为两部分,字符和二进制数据,字符部分用ret = self.conn.recv(1)接收,一次接收一个字节,结束标志是\r\n
#     字节部分用date = self.conn.recv(1024)接收。
import socket, threading, os, pymysql, json


class MyResponse(threading.Thread):
    def __init__(self, conn):
        super().__init__()
        self.conn = conn

    def upload(self, lis):
        with open('pic\\' + lis[1], 'wb') as f:
            filesize = int(lis[2])
            while True:
                date = self.conn.recv(1024*1024)
                filesize -= len(date)
                f.write(date)
                if filesize == 0:
                    print('over,fs:', filesize)
                    self.conn.sendall(b'ok')
                    break
        print('uploaded')

    def download(self, lis):
        size = os.path.getsize(lis[1])
        massage = 'size#' + str(size) + '\r\n'
        self.conn.sendall(massage.encode())
        with open(lis[1], 'rb') as f:
            self.conn.sendfile(f)
        print('downloaded')

    def sql(self, lis):
        sql = lis[1]
        connection = pymysql.connect(host="localhost", user="root",
                                     password="tangjun112", database="mydb",
                                     charset="utf8")
        try:
            # 2 . 创建游标对
            with connection.cursor(cursor=pymysql.cursors.DictCursor) as cursor:
            # with connection.cursor(这里添加参数以后会输出字段名,刚好可以包装成json) as cursor:
                # 3 . 执行 SQL 操作
                # sql = "select name,userid from user where userid>%(id)s"
                # sql ="select name,userid from user where userid>3"
                cursor.execute(sql)
                # 4 . 提取结果集
                result_set = cursor.fetchall()
                # print(result_set)
                # [{'name': 'xiaodong', 'userid': 4}, {'name': 'xiaodong111', 'userid': 5}, {'name': '大规模', 'userid': 6},
                #  {'name': '大规模', 'userid': 7}, {'name': '大规模', 'userid': 8}, {'name': '大规模', 'userid': 9}]
                # for row in result_set:
                #     print(row[0], row[1])
                    # 这里可以使用josn格式向客户端输出数据,获得一下row(0)row(1)对应的字段名,
                jsons = json.dumps(result_set)
                self.conn.sendall(jsons.encode())
            # with 代码块结束 5 . 关闭游标 with语句会自动释放资源。

        finally:
            # 6 . 关闭数据连接
            connection.close()
        print('sqlover')

    def run(self) -> None:
        print('有连接进入...')
        buf = []
        flag = False
        while True:
            ret = self.conn.recv(1)
            if flag:  # 当读到\r时把flag设为True
                if ret == b'\n':
                    mes = b''.join(buf).decode()
                    lis = mes.split('#')
                    # if lis[0] == 'upload':
                    #     self.upload(lis)
                    #     break
                    # if lis[0] == 'download':
                    #     self.download(lis)
                    #     break
                    # if lis[0] == 'sql':
                    #     self.sql(lis)
                    #     break

                    eval('self.'+lis[0]+"(lis)")
                    break
            if ret == b'\r':
                flag = True
                continue
            else:
                flag = False
            buf.append(ret)

        self.conn.close()


s = socket.socket()
s.bind(("", 8888))
s.listen(5)
print('服务器准备就绪')
while True:
    conn, addr = s.accept()  # 阻塞,等待客户端连接
    MyResponse(conn).start()


# s.close() 服务器是不需要关闭的

 

二、client

import socket, os, json


def sql(s) -> list:
    conn = socket.socket()
    conn.connect(('localhost', 8888))
    conn.sendall(('sql#'+s+'\r\n').encode())
    ret = conn.recv(1024*1024*100)  # 返回的数据最大为100M
    conn.close()
    lis = json.loads(ret.decode())
    return lis


def upload(path):
    conn = socket.socket()
    conn.connect(('localhost', 8888))

    file = open(path, 'rb')
    name = os.path.basename(path)
    size = os.path.getsize(path)

    massage = 'upload#'+name+'#'+str(size)+'\r\n'
    # massage = 'upload#001.jpg#346345\r\n'  \r\n 作用是message结束标志
    conn.sendall(massage.encode())
    conn.sendfile(file)  # 一次就读完,如果是大文件怎么办
    # conn.sendall(file.read())  # 也可以这样
    print(conn.recv(1024).decode())
    conn.close()


def download(filestr):
    conn = socket.socket()
    conn.connect(('localhost', 8888))

    massage = 'download#' + filestr + '\r\n'
    conn.sendall(massage.encode())
    name = os.path.basename(filestr)

    buf = []
    flag = False
    while True:
        ret = conn.recv(1)
        if flag:  # 当读到\r时把flag设为True
            if ret == b'\n':
                mes = b''.join(buf).decode()
                lis = mes.split('#')
                if lis[0] == 'size':
                    filesize = int(lis[1])
                    break
        if ret == b'\r':
            flag = True
            continue
        else:
            flag = False
        buf.append(ret)

    with open('F:\\'+name, 'wb') as f:
        while True:
            date = conn.recv(1024 * 1024)
            filesize -= len(date)
            f.write(date)
            if filesize == 0:
                print('client download over')
                break
    conn.close()


# # 下面是测试代码
# lis = sql('select name,userid from user where userid>3')
# upload('F:\pic\\3833.jpg')
# download('pic\\082.mp3')
# print(lis)

 

posted @ 2020-11-07 15:07  老谭爱blog  阅读(193)  评论(0)    收藏  举报