blob: 37fe6a82deb3ba8e92ce1067859737437eaa00fe [file] [log] [blame]
Mark Slee89e2bb82007-03-01 00:20:36 +00001# Copyright (c) 2006- Facebook
2# Distributed under the Thrift Software License
3#
4# See accompanying file LICENSE or visit the Thrift site at:
5# http://developers.facebook.com/thrift/
6
Mark Sleecde2b612006-09-03 21:13:07 +00007from TTransport import *
8import socket
9
10class TSocket(TTransportBase):
11
12 """Socket implementation of TTransport base."""
13
David Reissc16a8f62007-12-14 23:46:47 +000014 def __init__(self, host='localhost', port=9090, unix_socket=None):
15 """Initialize a TSocket
16
17 @param host(str) The host to connect to.
18 @param port(int) The (TCP) port to connect to.
19 @param unix_socket(str) The filename of a unix socket to connect to.
20 (host and port will be ignored.)
21 """
22
Mark Sleecde2b612006-09-03 21:13:07 +000023 self.host = host
Aditya Agarwal9bae5e72007-02-07 02:36:56 +000024 self.port = port
Mark Sleecde2b612006-09-03 21:13:07 +000025 self.handle = None
David Reissc16a8f62007-12-14 23:46:47 +000026 self._unix_socket = unix_socket
27 self._timeout = None
David Reiss0c90f6f2008-02-06 22:18:40 +000028
Mark Slee4f0fed62006-10-02 17:50:08 +000029 def setHandle(self, h):
Mark Sleec9676562006-09-05 17:34:52 +000030 self.handle = h
31
Mark Sleecde2b612006-09-03 21:13:07 +000032 def isOpen(self):
Aditya Agarwalf954f972007-02-06 01:26:12 +000033 return self.handle != None
34
35 def setTimeout(self, ms):
David Reissc16a8f62007-12-14 23:46:47 +000036 if ms is None:
37 self._timeout = None
James Wange168d5e2007-07-24 23:59:51 +000038 else:
David Reissc16a8f62007-12-14 23:46:47 +000039 self._timeout = ms/1000.0
David Reiss0c90f6f2008-02-06 22:18:40 +000040
David Reissc16a8f62007-12-14 23:46:47 +000041 if (self.handle != None):
42 self.handle.settimeout(self._timeout)
Mark Sleecde2b612006-09-03 21:13:07 +000043
David Reissc16a8f62007-12-14 23:46:47 +000044 def _resolveAddr(self):
45 if self._unix_socket is not None:
46 return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None, self._unix_socket)]
47 else:
48 return socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE | socket.AI_ADDRCONFIG)
David Reiss0c90f6f2008-02-06 22:18:40 +000049
Mark Sleecde2b612006-09-03 21:13:07 +000050 def open(self):
Mark Slee92195ae2007-02-21 05:16:30 +000051 try:
David Reissc16a8f62007-12-14 23:46:47 +000052 res0 = self._resolveAddr()
Mark Slee22974602007-07-06 22:20:19 +000053 for res in res0:
54 self.handle = socket.socket(res[0], res[1])
David Reissc16a8f62007-12-14 23:46:47 +000055 self.handle.settimeout(self._timeout)
Mark Slee22974602007-07-06 22:20:19 +000056 try:
57 self.handle.connect(res[4])
58 except socket.error, e:
59 if res is not res0[-1]:
60 continue
61 else:
62 raise e
63 break
Mark Slee92195ae2007-02-21 05:16:30 +000064 except socket.error, e:
Mark Slee76791962007-03-14 02:47:35 +000065 raise TTransportException(TTransportException.NOT_OPEN, 'Could not connect to %s:%d' % (self.host, self.port))
Mark Sleecde2b612006-09-03 21:13:07 +000066
67 def close(self):
Mark Sleed788b2e2006-09-07 01:26:35 +000068 if self.handle != None:
69 self.handle.close()
70 self.handle = None
Mark Sleecde2b612006-09-03 21:13:07 +000071
Mark Sleecde2b612006-09-03 21:13:07 +000072 def read(self, sz):
73 buff = self.handle.recv(sz)
Mark Sleec9676562006-09-05 17:34:52 +000074 if len(buff) == 0:
Mark Slee4f0fed62006-10-02 17:50:08 +000075 raise TTransportException('TSocket read 0 bytes')
Mark Sleecde2b612006-09-03 21:13:07 +000076 return buff
77
78 def write(self, buff):
Mark Sleec9676562006-09-05 17:34:52 +000079 sent = 0
80 have = len(buff)
81 while sent < have:
82 plus = self.handle.send(buff)
83 if plus == 0:
Mark Slee92195ae2007-02-21 05:16:30 +000084 raise TTransportException('TSocket sent 0 bytes')
Mark Sleec9676562006-09-05 17:34:52 +000085 sent += plus
86 buff = buff[plus:]
Mark Sleecde2b612006-09-03 21:13:07 +000087
88 def flush(self):
89 pass
Mark Sleec9676562006-09-05 17:34:52 +000090
91class TServerSocket(TServerTransportBase):
92
93 """Socket implementation of TServerTransport base."""
94
95 def __init__(self, port):
96 self.port = port
97 self.handle = None
Mark Slee256bdc42007-11-27 08:42:19 +000098
Mark Sleec9676562006-09-05 17:34:52 +000099 def listen(self):
Mark Slee256bdc42007-11-27 08:42:19 +0000100 res0 = socket.getaddrinfo(None, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE | socket.AI_ADDRCONFIG)
Mark Slee22974602007-07-06 22:20:19 +0000101 for res in res0:
102 if res[0] is socket.AF_INET6 or res is res0[-1]:
103 break
104
105 self.handle = socket.socket(res[0], res[1])
Mark Slee4f0fed62006-10-02 17:50:08 +0000106 self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
107 if hasattr(self.handle, 'set_timeout'):
108 self.handle.set_timeout(None)
Mark Slee22974602007-07-06 22:20:19 +0000109 self.handle.bind(res[4])
Mark Sleec9676562006-09-05 17:34:52 +0000110 self.handle.listen(128)
111
112 def accept(self):
113 (client, addr) = self.handle.accept()
114 result = TSocket()
Mark Slee4f0fed62006-10-02 17:50:08 +0000115 result.setHandle(client)
Mark Sleec9676562006-09-05 17:34:52 +0000116 return result
117
118 def close(self):
119 self.handle.close()
120 self.handle = None