軟體伺服器(附客戶端SDK)
阿新 • • 發佈:2020-11-07
一、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)