1. 程式人生 > 實用技巧 >軟體伺服器(附客戶端SDK)

軟體伺服器(附客戶端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)