00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 __facility__ = "Online"
00012 __abstract__ = "Socket class"
00013 __author__ = "Amedeo Perazzo <perazzo@slac.stanford.edu> SLAC - GLAST I&T/Online"
00014 __date__ = ("$Date: 2005/09/22 00:29:31 $").split(' ')[1]
00015 __version__ = "$Revision: 1.2 $"
00016 __release__ = "$Name: HEAD $"
00017 __credits__ = "SLAC"
00018
00019 import LICOS.copyright_SLAC
00020
00021 import socket
00022 import threading
00023
00024 class ConnectState:
00025 Disconnected = 0
00026 Waiting = 1
00027 Connected = 2
00028
00029 class Socket(object):
00030 TIMEOUT = 5
00031
00032 def __init__(self, portnumber):
00033 self.__port = portnumber
00034 self.__sock = None
00035 self.__host = None
00036 self.__lock = threading.Lock()
00037
00038 def connect(self, host=None, connectors=1):
00039 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
00040 sock.settimeout(self.TIMEOUT)
00041 try:
00042 if host is None:
00043
00044 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
00045 sock.settimeout(self.TIMEOUT)
00046 sock.bind(('', port))
00047 sock.listen(connectors)
00048 self.__sock,addr = sock.accept()
00049 else:
00050
00051 self.__sock = sock
00052 self.__sock.connect((host, self.__port))
00053 self.__host = host
00054
00055 except socket.error, msg:
00056 self.disconnect()
00057 raise RuntimeError, \
00058 'gSocket: unable to connect to %s on port %d: %s' \
00059 %(host, self.__port, str(msg))
00060 ss = 2*1024*1024
00061 self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, ss)
00062
00063 def disconnect(self):
00064 if self.isConnected():
00065 self.__sock.close()
00066 self.__sock = None
00067
00068 def isConnected(self):
00069 return (self.__sock is not None)
00070
00071 def socket(self):
00072 return self.__sock
00073
00074 def setSocket(self, sock):
00075 self.__sock = sock
00076
00077 def port(self):
00078 return self.__port
00079
00080 def setPort(self, port):
00081 self.__port = port
00082
00083 def lock(self):
00084 self.__lock.acquire()
00085
00086 def release(self):
00087 self.__lock.release()
00088
00089 def gettimeout(self):
00090 return self.__sock.gettimeout()
00091
00092 def settimeout(self, seconds):
00093 self.__sock.settimeout(seconds)
00094
00095 def send(self, packet):
00096 return self.__sock.send(packet)
00097
00098 def recv(self, size):
00099 return self.__sock.recv(size)
00100
00101 def sendall(self, packet):
00102 return self.__sock.sendall(packet)
00103
00104 def recvall(self, size):
00105
00106
00107
00108 data = ''
00109 remaining = size
00110 sock = self.__sock
00111 while remaining > 0:
00112 received = sock.recv(remaining)
00113 reclen = len(received)
00114 if reclen == 0: return received
00115 remaining -= reclen
00116 data += received
00117 return data
00118
00119 def purge(self):
00120 """!\brief Purge all stale data out of the socket.
00121 """
00122 max = 64*1024
00123 sock = self.__sock
00124 tmo = sock.gettimeout()
00125 sock.settimeout(0.1)
00126 received = ''
00127 size = 0
00128 while size != 0:
00129 try:
00130 received = sock.recv(max)
00131 except socket.error, e:
00132 if str(e) != "timed out": raise
00133 size = len(received)
00134
00135 sock.settimeout(tmo)
00136
00137 class ReconnectingSocket(Socket):
00138 def __init__(self, port, host):
00139 Socket.__init__(self, port)
00140 self.__name = name
00141 self.__host = host
00142
00143 def send(self, packet):
00144 self.lock()
00145 rv = super(ReconnectingSocket, self).send(packet)
00146 self.release()
00147 return rv
00148
00149 def recv(self, size):
00150 self.lock()
00151 rv = super(ReconnectingSocket, self).recv(size)
00152 self.release()
00153 return rv
00154
00155 def sendall(self, packet):
00156 self.lock()
00157 rv = super(ReconnectingSocket, self).sendall(packet)
00158 self.release()
00159 return rv
00160
00161 def recvall(self, packet):
00162 self.lock()
00163 rv = super(ReconnectingSocket, self).recvall(packet)
00164 self.release()
00165 return rv
00166
00167 def connect(self, host=None):
00168 """!\brief connect
00169
00170 Connect to the socket
00171 """
00172 self.__connection_state = ConnectState.Waiting
00173 self.__tries = 0
00174 self.__host = host
00175 self.__connect()
00176
00177 def disconnect(self):
00178 """!\brief disconnected
00179
00180 """
00181 self.__disconnect()
00182
00183 def timedout(self):
00184 """!\brief timedout
00185 """
00186 self.__disconnect()
00187
00188 def __disconnect(self):
00189
00190 super(ReconnectingSocket, self).disconnect()
00191
00192 self.__connection_notthere()
00193
00194 def __connection_notthere(self):
00195
00196 if self.__connection_state == ConnectState.Connected:
00197 log.error("Socket disconnected, trying to reconnect" )
00198 self.__connection_state = ConnectState.Waiting
00199 self.__connect()
00200
00201 def __connect(self):
00202
00203 connecthdlr = threading.Thread(None, self.__connection_handler, 'ConnectHandler',())
00204 connecthdlr.setDaemon(True)
00205 connecthdlr.start()
00206
00207 def __connection_handler(self):
00208 while (True):
00209 try:
00210 super(ReconnectingSocket, self).connect(self.__host)
00211 log.info("Socket is now connected")
00212 self.__connection_state = ConnectState.Connected
00213 self.__tries = 0
00214 break
00215 except RuntimeError, msg:
00216 if self.__tries == 0:
00217 log.error(msg)
00218 self.__tries += 1
00219 state = self.__connection_state
00220 if state == ConnectState.Disconnected: break
00221 time.sleep(3)
00222
00223
00224