Subversion Repositories HomeAutomation

Rev

Rev 743 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 743 Rev 800
1
import socket
1
import socket
2
from threading import Thread
2
from threading import Thread
3
from threading import Lock
3
from threading import Lock
4
import logging as log
4
import logging as log
5
import time
5
import time
6
 
6
 
7
class TCPServerThread(Thread):
7
class TCPServerThread(Thread):
8
   
8
   
9
    ownerNotifier = None
9
    ownerNotifier = None
10
    sock = None
10
    sock = None
11
    terminated = False
11
    terminated = False
12
   
12
   
13
    clientSocks = []
13
    clientSocks = []
14
    clientSocksLock = None
14
    clientSocksLock = None
15
   
15
   
16
    def __init__ (self, sock, ownerNotifier):
16
    def __init__ (self, sock, ownerNotifier):
17
        Thread.__init__(self)
17
        Thread.__init__(self)
18
        self.sock = sock
18
        self.sock = sock
19
        self.ownerNotifier = ownerNotifier
19
        self.ownerNotifier = ownerNotifier
20
        self.clientSocks = [] # may not be gc'd between instances of object
20
        self.clientSocks = [] # may not be gc'd between instances of object
21
        self.clientSocksLock = Lock()
21
        self.clientSocksLock = Lock()
22
       
22
       
23
    def cleanup(self):
23
    def cleanup(self):
24
        self.sock.close()
24
        self.sock.close()
25
        self.clientSocksLock.acquire()
25
        self.clientSocksLock.acquire()
26
        for clsock, addr in self.clientSocks:
26
        for clsock, addr in self.clientSocks:
27
            clsock.close()
27
            clsock.close()
28
        self.clientSocksLock.release()
28
        self.clientSocksLock.release()
29
 
29
 
30
        if self.ownerNotifier is not None:
30
        if self.ownerNotifier is not None:
31
            self.ownerNotifier.notify(self.ownerNotifier.TERMINATE)
31
            self.ownerNotifier.notify(self.ownerNotifier.TERMINATE)
32
 
32
 
33
    def run(self):
33
    def run(self):
34
        try:
34
        try:
35
            log.debug('TCPServerThread.run')
35
            log.debug('TCPServerThread.run')
36
            while not self.terminated:
36
            while not self.terminated:
37
                try:
37
                try:
38
                    conn, addr = self.sock.accept()
38
                    conn, addr = self.sock.accept()
39
                    print 'Client connected from ' + str(addr)
39
                    print 'Client connected from ' + str(addr)
40
                    conn.setblocking(0)
40
                    conn.setblocking(0)
41
                    self.clientSocksLock.acquire()
41
                    self.clientSocksLock.acquire()
42
                    self.clientSocks.append((conn, addr))
42
                    self.clientSocks.append((conn, addr))
43
                    self.clientSocksLock.release()
43
                    self.clientSocksLock.release()
44
                except socket.timeout:
44
                except socket.timeout:
45
                    pass
45
                    pass
46
            self.cleanup()
46
            self.cleanup()
47
        except: # sys.excepthook does not work in threads
47
        except: # sys.excepthook does not work in threads
48
            import traceback
48
            import traceback
49
            traceback.print_exc()
49
            traceback.print_exc()
50
            self.terminated = True
50
            self.terminated = True
51
            self.cleanup()
51
            self.cleanup()
52
   
52
   
53
    def terminate(self):
53
    def terminate(self):
54
        log.debug('TCPServerThread.terminate')
54
        log.debug('TCPServerThread.terminate')
55
        self.terminated = True
55
        self.terminated = True
56
 
56
 
57
class TCPServer():
57
class TCPServer():
58
   
58
   
59
    serverThread = None
59
    serverThread = None
60
    ownerNotifier = None
60
    ownerNotifier = None
61
    port = 50007
61
    port = 50007
62
    host = ''
62
    host = ''
63
   
63
   
64
    def __init__(self, port, ownerNotifier = None):
64
    def __init__(self, port, ownerNotifier = None):
65
        self.port = port
65
        self.port = port
66
        self.ownerNotifier = ownerNotifier
66
        self.ownerNotifier = ownerNotifier
67
       
67
       
68
    def start(self):
68
    def start(self):
69
        if self.serverThread is not None:
69
        if self.serverThread is not None:
70
            log.debug('TCPServer is already running')
70
            log.debug('TCPServer is already running')
71
            return
71
            return
72
        try:
72
        try:
73
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
73
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
74
        except Exception, e:
74
        except Exception, e:
75
            print 'TCP Server start failed:', e
75
            print 'TCP Server start failed:', e
76
            return False
76
            return False
77
        try:
77
        try:
78
            s.bind((self.host, self.port))
78
            s.bind((self.host, self.port))
79
            s.listen(1)
79
            s.listen(1)
80
            s.settimeout(0.5)
80
            s.settimeout(0.5)
81
        except Exception, e:
81
        except Exception, e:
82
            print 'TCP Server start failed:', e
82
            print 'TCP Server start failed:', e
83
            s.close()
83
            s.close()
84
            return False
84
            return False
85
        try:
85
        try:
86
            self.serverThread = TCPServerThread(s, self.ownerNotifier)
86
            self.serverThread = TCPServerThread(s, self.ownerNotifier)
87
            self.serverThread.start()
87
            self.serverThread.start()
88
        except Exception, e:
88
        except Exception, e:
89
            print 'TCP Server start failed:', e
89
            print 'TCP Server start failed:', e
90
            if self.serverThread is not None and self.serverThread.running():
90
            if self.serverThread is not None and self.serverThread.running():
91
                self.serverThread.terminate()
91
                self.serverThread.terminate()
92
            s.close()
92
            s.close()
93
            return False
93
            return False
94
        return True
94
        return True
95
 
95
 
96
    def stop(self):
96
    def stop(self):
97
        if self.running():
97
        if self.running():
98
            self.serverThread.terminate()
98
            self.serverThread.terminate()
99
        else:
99
        else:
100
            log.debug('TCPServer not started, or already stopped')
100
            log.debug('TCPServer not started, or already stopped')
101
 
101
 
102
    def running(self):
102
    def running(self):
103
        if self.serverThread is not None:
103
        if self.serverThread is not None:
104
            return not self.serverThread.terminated
104
            return not self.serverThread.terminated
105
        else:
105
        else:
106
            return False
106
            return False
107
       
107
       
108
    def getClients(self):
108
    def getClients(self):
109
        return self.serverThread.clientSocks
109
        return self.serverThread.clientSocks
110
 
110
 
111
    def readAll(self):
111
    def readAll(self):
112
        cldata = []
112
        cldata = []
113
        self.serverThread.clientSocksLock.acquire()
113
        self.serverThread.clientSocksLock.acquire()
114
        for clsock,addr in self.serverThread.clientSocks:
114
        for clsock,addr in self.serverThread.clientSocks:
115
            try:
115
            try:
116
                data = clsock.recv(1024)
116
                data = clsock.recv(1024)
117
            except Exception, e:
117
            except Exception, e:
118
                log.debug('TCPServer client ' + str(addr) + ' socket error: ' + str(e))
118
                log.debug('TCPServer client ' + str(addr) + ' socket error: ' + str(e))
119
                self.serverThread.clientSocksLock.release()
119
                self.serverThread.clientSocksLock.release()
120
                return None
120
                return None
121
            cldata.append((addr, data))
121
            cldata.append((addr, data))
122
        self.serverThread.clientSocksLock.release()
122
        self.serverThread.clientSocksLock.release()
123
        return cldata
123
        return cldata
124
 
124
 
125
    def writeAll(self, data):
125
    def writeAll(self, data):
126
        self.serverThread.clientSocksLock.acquire()
126
        self.serverThread.clientSocksLock.acquire()
127
        for clsock,addr in self.serverThread.clientSocks:
127
        for clsock,addr in self.serverThread.clientSocks:
128
            try:
128
            try:
129
                clsock.send(data)
129
                clsock.send(data)
130
            except Exception, e:
130
            except Exception, e:
131
                log.debug('TCPServer client ' + str(addr) + ' socket error: ' + str(e))
131
                log.debug('TCPServer client ' + str(addr) + ' socket error: ' + str(e))
132
                self.serverThread.clientSocks.remove((clsock,addr))
132
                self.serverThread.clientSocks.remove((clsock,addr))
133
                self.serverThread.clientSocksLock.release()
133
                self.serverThread.clientSocksLock.release()
134
                return False
134
                return False
135
        self.serverThread.clientSocksLock.release()
135
        self.serverThread.clientSocksLock.release()
136
        return True
136
        return True
137
 
137