00001 #!/usr/local/bin/python 00002 # 00003 # Copyright 2004 00004 # by 00005 # The Board of Trustees of the 00006 # Leland Stanford Junior University. 00007 # All rights reserved. 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/10/28 22:02:14 $").split(' ')[1] 00015 __version__ = "$Revision: 2.13 $" 00016 __release__ = "$Name: R04-12-00 $" 00017 __credits__ = "SLAC" 00018 00019 import LATTE.copyright_SLAC 00020 00021 import socket 00022 import threading 00023 import logging as log 00024 00025 class Socket(object): 00026 __TIMEOUT = 5 00027 00028 def __init__(self, portnumber): 00029 self.__port = portnumber 00030 self.__sock = None 00031 self.__host = None 00032 self.__lock = threading.Lock() 00033 00034 def connect(self, host): 00035 if host is None: 00036 raise RuntimeError, 'gSocket: host server name not specified' 00037 try: 00038 self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 00039 self.__sock.settimeout(Socket.__TIMEOUT) # TMOs are not handled correctly 00040 self.__sock.connect((host, self.__port)) 00041 self.__host = host 00042 except socket.error, msg: 00043 self.disconnect() 00044 raise RuntimeError, \ 00045 'gSocket: unable to connect to %s on port %d: %s' \ 00046 %(host, self.__port, str(msg)) 00047 ss = 2*1024*1024 00048 self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, ss) 00049 00050 def disconnect(self): 00051 if self.isConnected(): 00052 self.__sock.close() 00053 self.__sock = None 00054 00055 def isConnected(self): 00056 return (self.__sock is not None) 00057 00058 def socket(self): 00059 return self.__sock 00060 00061 def setSocket(self, sock): 00062 self.__sock = sock 00063 00064 def port(self): 00065 return self.__port 00066 00067 def setPort(self, port): 00068 self.__port = port 00069 00070 def lock(self): 00071 self.__lock.acquire() 00072 00073 def release(self): 00074 self.__lock.release() 00075 00076 def gettimeout(self): 00077 return self.__sock.gettimeout() 00078 00079 def settimeout(self, seconds): 00080 self.__sock.settimeout(seconds) 00081 00082 def send(self, packet): 00083 return self.__sock.send(packet) 00084 00085 def recv(self, size): 00086 return self.__sock.recv(size) 00087 00088 def sendall(self, packet): 00089 return self.__sock.sendall(packet) 00090 00091 def recvall(self, size): 00092 # The following is not supported on Windows, at least. 00093 # return self.__sock.recv(size, socket.MSG_WAITALL) 00094 00095 data = '' 00096 remaining = size 00097 sock = self.__sock 00098 count = 0 00099 while remaining > 0: 00100 try: 00101 received = sock.recv(remaining) 00102 reclen = len(received) 00103 # When a recv returns 0 bytes, other side has closed 00104 if reclen == 0: return received 00105 remaining -= reclen 00106 data += received 00107 except socket.error, e: 00108 if str(e) != "timed out": raise # Throw away "timed out" exceptions 00109 log.warn("Exception seen in recvall: %s" % str(e)) 00110 if count > 5: 00111 raise 00112 count += 1 00113 return data 00114 00115 def purge(self): 00116 """\brief Purge all stale data out of the socket. 00117 """ 00118 max = 64*1024 00119 sock = self.__sock 00120 tmo = sock.gettimeout() 00121 size = 0 00122 sock.settimeout(0.1) 00123 try: 00124 # While loop will break on exception 00125 while True: 00126 received = sock.recv(max) 00127 # When a recv returns 0 bytes, other side has closed 00128 reclen = len(received) 00129 if reclen == 0: 00130 break 00131 size += reclen 00132 except socket.error, e: 00133 if str(e) != "timed out": raise # Throw away "timed out" exceptions 00134 sock.settimeout(tmo) 00135 return size