From 9b54936e288deeb6cdb647805ad7dd98401bc142 Mon Sep 17 00:00:00 2001 From: zmy Date: Sat, 28 Dec 2019 16:26:19 +0800 Subject: [PATCH] initial commit --- example.py | 8 + img/1.jpg | Bin 0 -> 34378 bytes img/2.jpg | Bin 0 -> 47291 bytes imshow/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 347 bytes imshow/__pycache__/client.cpython-37.pyc | Bin 0 -> 1463 bytes imshow/__pycache__/config.cpython-37.pyc | Bin 0 -> 182 bytes imshow/__pycache__/network.cpython-37.pyc | Bin 0 -> 13891 bytes imshow/__pycache__/parallel.cpython-37.pyc | Bin 0 -> 4311 bytes imshow/__pycache__/server.cpython-37.pyc | Bin 0 -> 2206 bytes imshow/__pycache__/utils.cpython-37.pyc | Bin 0 -> 3932 bytes imshow/__pycache__/wrap.cpython-37.pyc | Bin 0 -> 1429 bytes imshow/client.py | 42 ++ imshow/config.py | 1 + imshow/network.py | 447 +++++++++++++++++++++ imshow/parallel.py | 129 ++++++ imshow/server.py | 72 ++++ imshow/utils.py | 139 +++++++ imshow/wrap.py | 34 ++ server.py | 4 + 19 files changed, 876 insertions(+) create mode 100644 example.py create mode 100644 img/1.jpg create mode 100644 img/2.jpg create mode 100644 imshow/__pycache__/__init__.cpython-37.pyc create mode 100644 imshow/__pycache__/client.cpython-37.pyc create mode 100644 imshow/__pycache__/config.cpython-37.pyc create mode 100644 imshow/__pycache__/network.cpython-37.pyc create mode 100644 imshow/__pycache__/parallel.cpython-37.pyc create mode 100644 imshow/__pycache__/server.cpython-37.pyc create mode 100644 imshow/__pycache__/utils.cpython-37.pyc create mode 100644 imshow/__pycache__/wrap.cpython-37.pyc create mode 100644 imshow/client.py create mode 100644 imshow/config.py create mode 100644 imshow/network.py create mode 100644 imshow/parallel.py create mode 100644 imshow/server.py create mode 100644 imshow/utils.py create mode 100644 imshow/wrap.py create mode 100644 server.py diff --git a/example.py b/example.py new file mode 100644 index 0000000..a29f729 --- /dev/null +++ b/example.py @@ -0,0 +1,8 @@ +from imshow.client import client +import cv2 + +img1 = cv2.imread('./img/1.jpg') +img2 = cv2.imread('./img/2.jpg') +while True: + client.imshow('Name', img1, waitKey=1) + client.imshow('Name', img2, waitKey=1) \ No newline at end of file diff --git a/img/1.jpg b/img/1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5deb79921f5c232e1e97bd2c4ba843cb50d24560 GIT binary patch literal 34378 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 GfB)HIYaG%5 literal 0 HcmV?d00001 diff --git a/img/2.jpg b/img/2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..891dd49488107262da98ba3b17d964ca3a3dbecb GIT binary patch literal 47291 zcmb@tcUY6p^C%hw1p!5rUR6M(t5j+ESO5V5={<-@4ZYVyKtQ^HfC3VcUL(B|sSyF` z1PCn&MS5rFG*CDR*=C^)}FWdfUw0;x;V?Kufu<0oVYyZS8zKpS*hY^4})@*YAIt``=%L zssDPyxWvD0{pL!K5Q5&&QTTFea&&_=;(wF<-y`&I?S1ShMI_2?Z|CXlOX=`i3N8@f z>-jJKfr7JmQ#wV#bN(b zf8hV~xfBur!*gdJPgmQZ+pnbmP5%E2zV?9>J^+Ac9-cwo&W=vLx1Uf($^N#cyPc%? z?MDwD$^!uZj`@E*^+5kWV@bs}_}_VvivWNM;^N|>^}qA95CA|mr6zszf9Ks-005X7 z0Dxc3p0?h$|7q{v`M=~qSrz-m0KheK0N~aLrH-YKgY={Slv6Q21pqEDTwEO70|02# z0D$w47Z+#WFD}mW0RZYb0N|(l1sd=SaEXfQ-_QR9>dVys!W9}C>dUlOXlehw>8>(d zrK6*#qot+4Mo-VcNCDcb*O{&{UjG;Ww~>FV|67alVWgv_`Y85zC!5|Jp+ZH{syJ{)YO+KoxMy$S?N?^ zlyU$K^W~d&9zMBpOW&6Et{2Or@RU3{fv44-tOlcaLFqT%5m)Ki*f}`4gzgF77ZH__ zm6KO^toZD?n!3gdO)WzsV-r)#z}vmGcW`uacJcA`^A89N3XXgq6&>>-HZC>oQ+h_` z=Py~`^9u@#ic3n%YHI818ycIMTe`Y?di#*S`hSm&PfSjsre|g`Slsf;>e}D+jlKPY z!z02m@#OShzNjdC{xA41#{MsSF;n=uM41B`+JE_?x)eaUshMdm-+6fD<`aEdTd!Mp zABEGgJWa`~?z}1>ZGdNe<2_2xCMbgu+WVKa|8VyIjIoISPn`X4#{QeHSpXw76=m|M znE^lmiRpWs*qlOFoQPN2KY-PAb&-FHON!oIGE9+|eJn8Naul621_Wk^nf0wmJpVD? zn37J~EE+lFUAEVoN>dwEM)B(DPR<8{yF&;h#MfXmSEV$$;+Fx@$`TpYWj^bm6bz8= zt<-OT>f9(siawQ{0XEgH)CFPrrN0uhKGji99j>≤1EELVFSZ9W#kAdN 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

20{(xv?nO` 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%0Dp6GncnLY*xX_o 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 E13b`-+yDRo literal 0 HcmV?d00001 diff --git a/imshow/__pycache__/__init__.cpython-37.pyc b/imshow/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06d1a855490df72221f3c414f5ce52ebc421276b GIT binary patch literal 347 zcmXxgK}y6h6b9g=P17O{cmOZZjRz1JL|1~&Vg@%MSW5e5CYUrONh$Rzp1>>3)|FRq zKq^!DEydU&K|>F@86XxAN74^YX(iveS0zWoLVkFN+7gmua-z tg0TUfOnZPG&fkKD)`R@NO*V}hRA`!;aXD3Y#`cqjHO1*Z{^TV+uRo$4_N)kc{-Oy6n_>gT02-9I|$=>nK53fef zuD$jtOK+k7f_-cc{eyJvDgQ!GeNV27HR#iOqo>i+_dU%wCnphs_Io?{FZ*&gL z1LGz1>MsC61kDKFkCapJoy^Hy?oxc`g3UOyHUrz^p0z!&eeP2t{aL^R;qy=gy!IUt zp{U&vQG4(3NJcW0H5t5jd0jR{bm^!+CE1>c`i}CZwHjcxZXU?`%n>KDDVn170e1e+ zZyo%r-`+x==cL>I2sx8sml}4hk~xe)A@y~sF2M}viAu6eW?=i{vY4dPRjdDW(CdHw zq}LyO)f)^3>C?xAjPWCf=7RAOdi5oMBuD{w1QpI5;jRb-6W$%=O!%;UXzJhR$yA}SxcA;6lhNlexbAYHqFj&`?9dozEBGr^k7f^7&$pwpd0aSXOKKxaqy z-YkO1ND$bT4!d>3F3L(9HZPSno-QwCp)hscJ}<|YQlFJYA;&r`3x%n0UnDXw3&Sdy z<^j-w)0`y>ePP_JoOT(^$!wwm2v;FO4d4%=PGI=w$FpanpDU@V(JEh###y-#qj4$Z z==Bm;jTSo1s?i(RLrcra`9*pCMrJapNsw}x2q-qp}u{Z z^prN~>fRBry+g2~5cfaJJ~)`GWjO<5O}0=KTe_wi_}#h4oMtl*cn8*n^TFMK0yBRb ztetJRBRDVI4YTVQdN&W&teV)E+Kz0zwYQCgx1+*`T74yg4ZC^;m4_OH!`1zBS%|cl zc5JSl+sB)ZE;}eo=eECjc01T~UE`+t)UYDSC6s8A>Tg%~-@<^)CZ*a(=d!Axig2~O zNp)}KE%fB!6BB|;5V?>)b?d4QCp12+$rF8~kpr)J!)EY${~3i>9knck33U1EQp<`n zCCBfKFC=Q#^;H96)F%jSj1DlhALP<7Ou)E#HMO$u0rfHdUc}G9u1*06y+_;dFdBhy z5sG$tEZROCuBKJ3>!IdILmZnZj`LD1GPE0Ue6>ij{fxqLP@f}U(H#M%pipr%Dy-;` zhBf;JKb$9N5yz`~?-9`bsNb8-rw3<%j$uRC`Xkm4B!p+^wv9V}H{d?r2dVd)BANCU z**l}~&uA~f5#N{t{7q~nt1qmR=1L~QFxa|pad4ElJ%=SQe7-;Q3(TVG0KgHP2DOjt S1Ch*We%f$CATy#4Q2Q^@ZeQX6 literal 0 HcmV?d00001 diff --git a/imshow/__pycache__/config.cpython-37.pyc b/imshow/__pycache__/config.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ca561f9d7ddc7076f3bccb6cc3aca9867b24ff8 GIT binary patch literal 182 zcmZ?b<>g`kg1P_M;zWS-V-N=h7=a82ATH(r5-AK(3@MDk44O<)oW=RMsU`W@sd;{y zjJH_9td$H!Oh8p&;+K!JRZM7cYEf}aRc>WWa!!6}N=$NoN@|R6WpQdwT1;t4W=?TT zP-<>|NvdaVVtQ(DMt*rvYEEimacWFvZZVJtRG*iYnXXq*d5gm)H$SB`C)Ez*p3gwc F002(gGiv|< literal 0 HcmV?d00001 diff --git a/imshow/__pycache__/network.cpython-37.pyc b/imshow/__pycache__/network.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9a3108ea2aa07f5524465726135080833bb853d GIT binary patch literal 13891 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 literal 0 HcmV?d00001 diff --git a/imshow/__pycache__/parallel.cpython-37.pyc b/imshow/__pycache__/parallel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2965ac603d396e7f4f60a392bda0fffd6b029aca GIT binary patch literal 4311 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 literal 0 HcmV?d00001 diff --git a/imshow/__pycache__/server.cpython-37.pyc b/imshow/__pycache__/server.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c724fde22dbbfcb663a95b9d49398a655d1b3d5 GIT binary patch literal 2206 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 Q!8zPn25$*}W2{f{FCRrg<^TWy literal 0 HcmV?d00001 diff --git a/imshow/client.py b/imshow/client.py new file mode 100644 index 0000000..67c25c6 --- /dev/null +++ b/imshow/client.py @@ -0,0 +1,42 @@ +import cv2 +import socket + +from imshow import wrap +from imshow import network +from imshow import parallel +from imshow import config + + +token = config.token +host = '192.168.123.222' +port = 12345 + +class ImageClient(): + def __init__(self, host, port, token): + self.host = host + self.port = port + self.token = token + self.sock = network.SocketConnection(parallel.daemon) + self.sock.connect(self.host, self.port) + self.sock.auth(self.token) + self.log = self.sock.log + + def imshow(self, name, img, waitKey=0): + self.log('Sending Image {0} to host {1}:{2}'.format(name, host, port)) + img = wrap.ImageMessage(img=img, name=name, wait=waitKey) + self.sock.send(img.tobytes()) + exit = False + self.log('Waiting for host message to exit.') + while not exit: + msg = self.sock.recv() + if msg.decode('utf-8') == 'continue': + exit = True + +client = ImageClient(host, port, token) + +if __name__ == '__main__': + img1 = cv2.imread('./img/1.jpg') + img2 = cv2.imread('./img/2.jpg') + while True: + client.imshow('Name', img1, waitKey=1) + client.imshow('Name', img2, waitKey=1) \ No newline at end of file diff --git a/imshow/config.py b/imshow/config.py new file mode 100644 index 0000000..429b81c --- /dev/null +++ b/imshow/config.py @@ -0,0 +1 @@ +token = 'sometoken' diff --git a/imshow/network.py b/imshow/network.py new file mode 100644 index 0000000..a08785f --- /dev/null +++ b/imshow/network.py @@ -0,0 +1,447 @@ +import socket +import zlib +import json +import struct +import queue + +from imshow import parallel + +class SocketMessage(): + def __init__(self, msg={}): + self.data = msg + self.type = 'empty' + + def encode(self): + pass + + def decode(self): + pass + + def tobytes(self): + self.encode() + js = {} + js['type'] = self.type + js['msg'] = self.data + js = json.dumps(js) + js = js.encode('utf-8') + byte = zlib.compress(js) + return byte + + def frombytes(self, byte): + js = zlib.decompress(byte) + js = js.decode('utf-8') + js = json.loads(js) + msg = js['msg'] + self.data = msg + self.decode() + +class SocketServer(): + def __init__(self, ip='0.0.0.0', port=12345, message_handler=None): + self.daemon = parallel.daemon + self.ip = ip + self.port = port + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.bind((self.ip, self.port)) + self.socket.listen(5) + self.terminate = False + self.handler = message_handler + + def handle_message(self, clientsocket, addr): + # print('Connection Established from clinet', addr) + if self.handler is not None: + self.handler(clientsocket, addr) + pass + + def loop(self): + while not self.terminate: + clientsocket,addr = self.socket.accept() + self.daemon.add_job( + self.handle_message, + args=[clientsocket, addr], + name='Client[{0}]'.format(addr) + ) + + def start(self, back=True): + if back: + self.daemon.add_job(self.loop, name='SocketMainLoop') + else: + self.loop() + +# what should a packet header contains: +# 1. message id +# 2. packet id +# 3. total packets +# 4. total size + +class PacketHeader(): + def __init__(self, mid=0, pid=0, pn=0, sz=0): + self.msg_id = mid + self.pkt_id = pid + self.pkt_num = pn + self.msg_sz = sz + self.header_size = 16 + + def tobytes(self): + b = struct.pack('LLLL', self.msg_id, self.pkt_id, self.pkt_num, self.msg_sz) + return b + + def frombytes(self, b): + self.msg_id, self.pkt_id, self.pkt_num, self.msg_sz = struct.unpack('LLLL', b) + return self + +class Packet(): + def __init__(self, header=PacketHeader(), msg=b''): + self.header = header + self.msg = msg + self.header_size = self.header.header_size + + def frombytes(self, b): + header = b[:self.header_size] + self.msg = b[self.header_size:] + self.header.frombytes(header) + return self + + def tobytes(self): + msg = b'' + self.header.msg_sz = len(self.msg) + msg += self.header.tobytes() + msg += self.msg + return msg + +class PacketFactory(): + def __init__(self, max_size=8192, log=None): + self.max_size = max_size + self.id = 0 + self.header_size = PacketHeader().header_size + self.log = print + if log != None: + self.log = log + + def to_packets(self, msg): + packets = [] + length = len(msg) + capacity = self.max_size - self.header_size + num_packets = int((length + capacity - 1) / capacity) + for i in range(num_packets): + header = PacketHeader(self.id, i, num_packets) + packet = Packet(header, msg[i*capacity:(i+1)*capacity]) + packets.append(packet) + self.id += 1 + return packets + + def from_packets(self, packets): + num_packet = len(packets) + self.log('Packet Number:', num_packet) + if num_packet == 0: + return None + msg_id = None + packet_id = 0 + message = b'' + + for packet in packets: + header = packet.header + if msg_id is None: + msg_id = header.msg_id + if num_packet != header.pkt_num: + self.log('Uncorrect Package Number') + self.log('get {0} while it should be {1}'.format(header.pkt_num, num_packet)) + return None + + if msg_id != header.msg_id: + self.log('Uncorrect Message id') + self.log('get {0} while it should be {1}'.format(header.pkt_num, msg_id)) + return None + if packet_id != header.pkt_id: + self.log('Uncorrect pkt id') + self.log('get {0} while it should be {1}'.format(header.pkt_id, packet_id)) + return None + message += packet.msg + packet_id += 1 + return message + +class AuthMessage(SocketMessage): + def __init__(self, token='None'): + super(AuthMessage, self).__init__() + self.token = token + self.type = 'auth' + self.stat = 0 + # stat: + # 0: auth client + # 1: auth success + # 2: auth failed. + + def encode(self): + self.data = {} + self.data['token'] = self.token + self.data['status'] = self.stat + + def decode(self): + self.token = self.data['token'] + self.stat = self.data['status'] + +class SocketConnection(): + def __init__(self, daemon, log_prefix=''): + self.sock = None + self.daemon = daemon + self.messages = queue.Queue() + self.terminated = False + self.factory = PacketFactory(log=self.log) + self.header_size = PacketHeader().header_size + self.loglevel = 2 + self.log_prefix = log_prefix + + # log level: + # 0 : debug + # 1 : message or info + # 2 : warning + # 3 : error + def log(self, *args, level=0, end='\n'): + if level >= self.loglevel: + print(self.log_prefix, end=' ') + for msg in args: + print(str(msg), end=' ') + print(end, end='') + + def start(self): + self.jid = self.daemon.add_job(self.recv_bare, name='connection') + + def SetSock(self, sock): + self.sock = sock + self.start() + + def connect(self, host, port): + if self.sock is None: + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.connect((host, port)) + self.log('Sock Connected', level=1) + else: + self.log('Socket has already established, ingoring connect.', level=2) + self.start() + + def auth(self, token): + if self.sock is None: + self.log('Socket not established, unable to auth.', level=3) + return None + auth_msg = AuthMessage(token) + msg = auth_msg.tobytes() + self.log('Sending Authentication Message.') + self.send(msg) + self.log('Waiting Authentication Status.') + msg = self.recv() + auth_msg.frombytes(msg) + self.log('Status Recived! auth_status =', auth_msg.__dict__) + if auth_msg.stat == 1: + self.log('Auth Success!', level=1) + else: + self.log('Auth Failed!', level=3) + self.close() + + def WaitAuth(self, token): + msg = self.recv() + auth_msg = AuthMessage() + auth_msg.frombytes(msg) + if auth_msg.token != token: + self.log('Authentication Failed!', level=1) + auth_msg = AuthMessage('InvalidAuth') + auth_msg.stat = 2 + self.send(auth_msg.tobytes()) + self.close() + else: + self.log('Authentication Success!', level=1) + auth_msg = AuthMessage('Welcome') + auth_msg.stat = 1 + self.send(auth_msg.tobytes()) + + def send(self, msg): + if self.terminated: + return False + packets = self.factory.to_packets(msg) + self.log('spliting message to {0} packets'.format(len(packets))) + for packet in packets: + self.sock.send(packet.tobytes()) + return True + + def commit_message(self, packets): + self.log('Generating final packet...') + full_msg = self.factory.from_packets(packets) + if full_msg is not None: + self.log('Valid package!') + self.messages.put(full_msg) + else: + self.log('Invalid package') + + def recv_bare(self): + msg_id = None + packets = [] + while not self.terminated: + raw_msg = None + try: + raw_msg = self.sock.recv(8192) + except (ConnectionAbortedError, ConnectionResetError): + self.log('Connection Stopped') + self.close() + continue + + if raw_msg is None or len(raw_msg) == 0: + self.close() + continue + if len(raw_msg) < self.header_size: + continue + + pkt = Packet(PacketHeader()) + pkt.frombytes(raw_msg) + packets.append(pkt) + + if msg_id is None: + msg_id = pkt.header.msg_id + + if msg_id != pkt.header.msg_id: + msg_id = pkt.header.msg_id + packets = [pkt] + continue + + if pkt.header.pkt_id == pkt.header.pkt_num - 1: + self.log('Finished') + self.commit_message(packets) + msg_id = None + packets = [] + + + def recv(self): + self.log('Getting messages') + msg = None + while msg is None and not self.terminated: + try: + msg = self.messages.get(timeout=0.1) + except queue.Empty: + msg = None + continue + return msg + self.log('Message Get Finished') + + def close(self): + self.terminated = True + self.sock.close() + + +class HttpServer(SocketServer): + def __init__(self): + super(HttpServer, self).__init__(port=80) + self.header = 'HTTP/1.1 200 OK\nServer: NaiveHttpServer\nConnection: close\nContent-Length: {0}\nContent-Type: text/html\n\n' + + def handle_message(self, clientsocket, addr): + # print('Connection Established from clinet', addr) + msg = clientsocket.recv(8192) + text = msg.decode('utf-8') + while '\n' in text: + text = text.replace('\n', '
') + info = '' + info += '

Hello, World

' + info += '

Your IP Address & Port

\n' + info += '

{0}

'.format(str(addr)) + info += '

Your Request

\n' + info += '

{0}

\n'.format(text) + info += '\n' + length = len(info) + # print('length =', length) + header = self.header.format(length) + msg = header + info + # print('msg:', msg) + clientsocket.send(msg.encode('utf-8')) + # print('message sent!') + clientsocket.close() + +class BridgeConnection(): + def __init__(self, client, server, num_threads=8): + self.client = client + self.server = server + self.daemon = parallel.ParallelHost(num_threads) + self.exit = False + self.client_terminated = False + self.server_terminated = False + + def is_terminated(self): + if self.client_terminated: + return True + else: + return False + + def client_recv_handler(self, msg): + # print('send message to server, size=', len(msg)) + self.server.send(msg) + + def stop(self): + self.daemon.stop('kill') + self.server.close() + print('connection terminated successfully.') + + def client_recv(self): + while True: + msg = self.client.recv(8192) + if len(msg) == 0: + self.exit = True + break + # print('message received from clinet, size=', len(msg)) + self.daemon.add_job(self.client_recv_handler, args=[msg]) + self.client_terminated = True + print('Client Recv terminated.') + + def server_recv_handler(self, msg): + # print('send message to client, size=', len(msg)) + self.client.send(msg) + + def server_recv(self): + while not self.exit: + try: + msg = self.server.recv(8192) + except ConnectionAbortedError: + break + if len(msg) == 0: + self.exit = True + continue + # print('message received from server, size=', len(msg)) + self.daemon.add_job(self.server_recv_handler, args=[msg]) + self.server_terminated = True + print('Server Recv terminated.') + + def run(self): + self.daemon.add_job(self.server_recv) + self.daemon.add_job(self.client_recv) + while not self.is_terminated(): + time.sleep(1) + self.stop() + +def SendMessage(host, port, msg): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((host, port)) + s.send(msg) + print('Message Sent!') + s.close() + + + +def portforward(dst_ip, dst_port, listen_ip, listen_port): + def port_forward_handler(clientsocket, addr): + print('Handling message from clinet', addr) + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((dst_ip, dst_port)) + print('Connect to dst server success!') + connection = BridgeConnection(clientsocket, s) + connection.run() + print('handler exited') + server = SocketServer(message_handler=port_forward_handler, ip=listen_ip, port=listen_port) + server.start() + +# if __name__ == '__main__': +# # let's try a port forwarding server using this socker server. +# portforward('192.168.233.101', 22, '0.0.0.0', 30001) +# portforward('192.168.233.102', 22, '0.0.0.0', 30002) + +# con = console.console('PortForward') +# con.interactive() + +if __name__ == '__main__': + server = HttpServer() + server.start() + import time + time.sleep(10000) \ No newline at end of file diff --git a/imshow/parallel.py b/imshow/parallel.py new file mode 100644 index 0000000..1643714 --- /dev/null +++ b/imshow/parallel.py @@ -0,0 +1,129 @@ +import threading +import queue +import time + +class Job(): + def __init__(self, func, args=[], kwargs={}, name=None): + if name == None: + name = 'job' + self.id = None + self.name = name + self.func = func + self.args = args + self.kwargs = kwargs + self.results = None + + def run(self): + self.results = self.func(*self.args, **self.kwargs) + + def set_name(self, name): + self.name = name + + def set_id(self, jid): + self.id = jid + + def __call__(self): + self.run() + +class Worker(threading.Thread): + def __init__(self, work_queue, finished_queue): + super(Worker, self).__init__() + self.queue = work_queue + self.finished = finished_queue + self.terminate = False + self.daemon=True + + def stop(self): + self.terminate = True + + def run(self): + while not self.terminate: + try: + task = self.queue.get(timeout=1) + task.run() + self.queue.task_done() + self.finished.put(task) + except queue.Empty: + pass + except KeyboardInterrupt: + print("you stop the threading") + +class ParallelHost(): + def __init__(self, num_threads=8): + self.num_threads = num_threads + self.workers = [] + self.tasks = queue.Queue() + self.results = queue.Queue() + self.rets = {} + self.id = 0 + for i in range(self.num_threads): + worker = Worker(self.tasks, self.results) + self.workers.append(worker) + for worker in self.workers: + worker.start() + + def __del__(self): + self.stop('kill') + + # soft stop: wait until all job done + # hard stop: stop even with unfinished job + # kill stop: whatever the thread is doing, exit. + def stop(self, mode='soft'): + print('Trying to stop.') + if mode == 'soft': + self.tasks.join() + print('All job finished.') + for worker in self.workers: + worker.stop() + if mode == 'kill': + worker.join(0.01) + + def commit(self, job): + self.id += 1 + job.set_id(self.id) + self.tasks.put(job) + return self.id + + def add_job(self, func, args=[], kwargs={}, name=None): + job = Job(func, args, kwargs, name) + return self.commit(job) + + def collect_all(self): + while not self.results.empty(): + task = self.results.get() + jid = task.id + self.rets[jid] = task.results + + def get_result(self, jid, block=False): + if jid in self.rets: + ret = self.rets[jid] + del self.rets[jid] + return ret + while True: + if self.results.empty() and not block: + break + task = self.results.get() + if task.jid == jid: + return task.results + else: + self.rets[task.jid] = task.results + + def clear_results(self): + while not self.results.empty(): + self.results.get() + self.rets = {} + +daemon = ParallelHost() + +if __name__ == '__main__': + host = ParallelHost() + + def loop_print(info, num): + for i in range(num): + print(info + ':' + str(i)) + time.sleep(1) + + for i in range(10): + host.add_job(loop_print, ["loop_print_{0}".format(i), 5]) + + host.terminate('kill') diff --git a/imshow/server.py b/imshow/server.py new file mode 100644 index 0000000..1e6f822 --- /dev/null +++ b/imshow/server.py @@ -0,0 +1,72 @@ +import socket +import queue +import time + +import cv2 + +from imshow import network +from imshow import wrap +from imshow import config +from imshow import parallel + +SocketServer = network.SocketServer +SocketMessage = network.SocketMessage +SocketConnection = network.SocketConnection + +class ImageServer(): + def __init__(self, ip, port): + self.server = SocketServer(ip=ip, port=port, message_handler=self.process_socket) + self.server.start() + self.id = 0 + self.finished_id = [] + self.imgs = queue.Queue() + + def process_socket(self, clientsocket, addr): + connection = SocketConnection(self.server.daemon, '[{0}]'.format(str(addr))) + connection.log('Connection extablished from {0}'.format(addr)) + connection.SetSock(clientsocket) + connection.log('Waiting for authentication...', level=1) + connection.WaitAuth(config.token) + while True: + message = connection.recv() + if message is None: + break + img = wrap.ImageMessage() + img.frombytes(message) + task = {} + task['img'] = img.img + task['name'] = img.name + task['wait'] = img.wait + task['id'] = self.id + task['source'] = addr + self.imgs.put(task) + self.id += 1 + connection.log('waiting for showing image') + while task['id'] not in self.finished_id: + time.sleep(0.01) + continue + connection.log('image shown!') + if not connection.send('continue'.encode('utf-8')): + connection.log('Exited') + break + connection.log('client {0} disconnected'.format(addr)) + + def show(self): + while True: + task = None + try: + task = self.imgs.get(timeout=0.1) + except queue.Empty: + cv2.waitKey(1) + continue + + img = task['img'] + name = task['name'] + wait = task['wait'] + cv2.imshow(name, img) + cv2.waitKey(wait) + self.finished_id.append(task['id']) + +if __name__ == '__main__': + server = ImageServer('0.0.0.0', 12345) + server.show() diff --git a/imshow/utils.py b/imshow/utils.py new file mode 100644 index 0000000..733075b --- /dev/null +++ b/imshow/utils.py @@ -0,0 +1,139 @@ +import pickle +import time +import os +import re +import platform + +def detect_platform(): + p = 'Unknown' + if platform.platform().find('Windows') != -1: + p = 'Windows' + elif platform.platform().find('Linux') != -1: + p = 'Linux' + return p + +def ensure_dir_exist(directory, show_info = True): + exist = os.path.isdir(directory) + if not exist: + print('directory', directory, ' not found, creating...') + os.mkdir(directory) + +def validateTitle(title): + rstr = r"[\/\\\:\*\?\"\<\>\|]" # '/ \ : * ? " < > |' + new_title = re.sub(rstr, " ", title) # 替换为空格 + return new_title + +def list2csv(l): + csv = '' + for item in l: + csv += str(item) + ',' + csv = csv[:-1] + return csv + +def clean_text(string): + if string is None: + return '' + while '\n' in string: + string = string.replace('\n', ' ') + splits = clean_split(string) + string = '' + for split in splits: + string += split + ' ' + string = string[:-1] + return string + +def clean_split(string, delimiter=' '): + sub_strs = string.split(delimiter) + splits = [] + for sub_str in sub_strs: + if sub_str is not '': + splits.append(sub_str) + return splits + +def remove_blank_in_endpoint(string): + length = len(string) + + first_index = 0 + for i in range(length): + if is_blank(string[first_index]): + first_index += 1 + else: + break + + last_index = length - 1 + for i in range(length): + if is_blank(string[last_index]): + last_index -= 1 + else: + break + last_index += 1 + return string[first_index:last_index] + +def is_blank(ch): + blank_ch = [' ', '\t', '\n'] + if ch in blank_ch: + return True + else: + return False + +def dict_to_arrtibute_string(attributes): + string = '' + for key in attributes: + string += key + '=\"{0}\";'.format(str(attributes[key])) + return string + +def attribute_string_to_dict(attrs): + attr_dict = {} + for attr in attrs: + attr_dict[attr[0]] = attr[1] + return attr_dict + +def save_python_object(obj, save_path): + with open(save_path, 'wb') as file: + pickle.dump(obj, file) + +def load_python_object(path): + with open(path, 'rb') as file: + return pickle.load(file) + +def delete_n(string): + while '\n' in string: + string = string.replace('\n', ' ') + return string + +def remove_additional_blank(string): + words = string.split(' ') + string = '' + for word in words: + if word is not '': + string += word + ' ' + return string[:-1] + +def formal_text(text): + text = delete_n(text) + text = remove_additional_blank(text) + return text + +def float2str(f, precision=2): + f = str(f) + f_base = f[:f.find('.') + precision] + return f_base + +# ========== time realted operation ========== # + +def str_day(): + day = time.strftime("%Y-%m-%d", time.localtime()) + return day + +def time2str(t): + localtime = time.localtime(int(t)) + return str_time(localtime) + +def str_time(local_time = None): + if local_time is None: + local_time = time.localtime() + day = time.strftime("%Y-%m-%d-%Hh-%Mm-%Ss)", local_time) + return day + +if __name__ == '__main__': + print(str_day()) diff --git a/imshow/wrap.py b/imshow/wrap.py new file mode 100644 index 0000000..32bee5b --- /dev/null +++ b/imshow/wrap.py @@ -0,0 +1,34 @@ +import numpy as np +import base64 +import json +import zlib +from imshow import network +SocketServer = network.SocketServer +SocketMessage = network.SocketMessage + +class ImageMessage(SocketMessage): + def __init__(self, img=None, name = 'Image', wait=0): + super(ImageMessage, self).__init__() + self.img = img + self.wait = wait + self.name = name + self.type = 'image' + + def encode(self): + img_bytes = self.img.tobytes() + img_bytes = base64.b64encode(img_bytes).decode('utf-8') + img_shape = self.img.shape + self.data['img'] = img_bytes + self.data['dtype'] = self.img.dtype.char + self.data['shape'] = img_shape + self.data['wait'] = self.wait + self.data['name'] = self.name + + def decode(self): + byte = base64.b64decode(self.data['img']) + img = np.frombuffer(byte, dtype=np.dtype(self.data['dtype'])) + img = img.reshape(self.data['shape']) + self.img = img + self.wait = self.data['wait'] + self.name = str(self.data['name']) + diff --git a/server.py b/server.py new file mode 100644 index 0000000..52d51d8 --- /dev/null +++ b/server.py @@ -0,0 +1,4 @@ +from imshow.server import ImageServer + +if __name__ == '__main__': + ImageServer('0.0.0.0', 12345).show()