1#!/usr/bin/env python3 2import sys 3import struct 4import signal 5from threading import Thread 6from datetime import datetime 7from socketserver import ThreadingTCPServer, StreamRequestHandler 8 9TARGET_WIDTH = 128 10TARGET_HEIGHT = 64 11PIXEL_PER_BYTE = 8 12 13BIN_FRAME_SIZE = int(TARGET_WIDTH * TARGET_HEIGHT / PIXEL_PER_BYTE) 14 15DEFAULT_PORT = 5678 16 17REQUEST_SIZE = 4 18STATUS_SUCCESS = 0 19STATUS_FAILURE = 255 20 21class EncodeHandler(StreamRequestHandler): 22 bitmapList = [] 23 24 def handle(self): 25 addr = self.request.getpeername() 26 print('Got connection from', addr) 27 28 while True: 29 startTime = datetime.now() 30 req = self.rfile.read(REQUEST_SIZE) 31 if not req: 32 break 33 # recv request from client 34 frameId = int.from_bytes(req, 'big') # bytes request 35 36 # prepare response 37 status, body = None, bytes() 38 if frameId < len(EncodeHandler.bitmapList): 39 status = STATUS_SUCCESS 40 body = EncodeHandler.bitmapList[frameId] 41 else: 42 status = STATUS_FAILURE 43 print('frameId out of range!') 44 break 45 # response header is: status(4B) + body length(4B) 46 head = struct.pack('>II', status, len(body)) 47 48 # send response(header + body) to client 49 self.wfile.write(head + body) 50 51 currentTime = datetime.now() 52 timeCost = currentTime - startTime 53 print('frameId:', frameId, 'timeCost: %.3f' % timeCost.total_seconds()) 54 print('handle request from', addr, 'done!') 55 self.wfile.close() 56 57def load_video_bin(binFile): 58 binFrames = [] 59 print('loading', binFile, '...') 60 with open(binFile, 'rb') as f: 61 while True: 62 blob = f.read(BIN_FRAME_SIZE) 63 if len(blob) == 0: 64 break 65 binFrames.append(blob) 66 print('load', binFile, 'done!') 67 return binFrames 68 69def main(): 70 if len(sys.argv) < 2: 71 print("Usage: {} binFile [port]\n\t".format(sys.argv[0])) 72 exit(-1) 73 74 binFile = sys.argv[1] 75 port = DEFAULT_PORT if len(sys.argv) < 3 else int(sys.argv[2]) 76 77 print('binFile:', binFile, 'port:', port) 78 server = ThreadingTCPServer(('', port), EncodeHandler) 79 80 def sigint_handler(signum, frame): 81 print('sig {} raised: {}'.format(signum, frame)) 82 server.socket.close() 83 server.shutdown() 84 sys.exit(0) 85 signal.signal(signal.SIGINT, sigint_handler) # main thread will handle signals 86 87 try: 88 EncodeHandler.bitmapList = load_video_bin(binFile) 89 waiterThread = Thread(target=server.serve_forever, args=()) 90 waiterThread.start() 91 waiterThread.join() 92 except Exception as e: 93 print('exception raised:', e) 94 finally: 95 server.socket.close() 96 server.shutdown() 97 98if __name__ == "__main__": 99 main() 100