blob: 146820d82747eaa319a89538f62687f65eafac30 [file] [log] [blame]
Mark Slee89e2bb82007-03-01 00:20:36 +00001#!/usr/bin/env python
2#
3# Copyright (c) 2006- Facebook
4# Distributed under the Thrift Software License
5#
6# See accompanying file LICENSE or visit the Thrift site at:
7# http://developers.facebook.com/thrift/
8
Mark Sleecde2b612006-09-03 21:13:07 +00009from TTransport import *
10import socket
11
12class TSocket(TTransportBase):
13
14 """Socket implementation of TTransport base."""
15
David Reissc16a8f62007-12-14 23:46:47 +000016 def __init__(self, host='localhost', port=9090, unix_socket=None):
17 """Initialize a TSocket
18
19 @param host(str) The host to connect to.
20 @param port(int) The (TCP) port to connect to.
21 @param unix_socket(str) The filename of a unix socket to connect to.
22 (host and port will be ignored.)
23 """
24
Mark Sleecde2b612006-09-03 21:13:07 +000025 self.host = host
Aditya Agarwal9bae5e72007-02-07 02:36:56 +000026 self.port = port
Mark Sleecde2b612006-09-03 21:13:07 +000027 self.handle = None
David Reissc16a8f62007-12-14 23:46:47 +000028 self._unix_socket = unix_socket
29 self._timeout = None
30
Mark Slee4f0fed62006-10-02 17:50:08 +000031 def setHandle(self, h):
Mark Sleec9676562006-09-05 17:34:52 +000032 self.handle = h
33
Mark Sleecde2b612006-09-03 21:13:07 +000034 def isOpen(self):
Aditya Agarwalf954f972007-02-06 01:26:12 +000035 return self.handle != None
36
37 def setTimeout(self, ms):
David Reissc16a8f62007-12-14 23:46:47 +000038 if ms is None:
39 self._timeout = None
James Wange168d5e2007-07-24 23:59:51 +000040 else:
David Reissc16a8f62007-12-14 23:46:47 +000041 self._timeout = ms/1000.0
42
43 if (self.handle != None):
44 self.handle.settimeout(self._timeout)
Mark Sleecde2b612006-09-03 21:13:07 +000045
David Reissc16a8f62007-12-14 23:46:47 +000046 def _resolveAddr(self):
47 if self._unix_socket is not None:
48 return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None, self._unix_socket)]
49 else:
50 return socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE | socket.AI_ADDRCONFIG)
51
Mark Sleecde2b612006-09-03 21:13:07 +000052 def open(self):
Mark Slee92195ae2007-02-21 05:16:30 +000053 try:
David Reissc16a8f62007-12-14 23:46:47 +000054 res0 = self._resolveAddr()
Mark Slee22974602007-07-06 22:20:19 +000055 for res in res0:
56 self.handle = socket.socket(res[0], res[1])
David Reissc16a8f62007-12-14 23:46:47 +000057 self.handle.settimeout(self._timeout)
Mark Slee22974602007-07-06 22:20:19 +000058 try:
59 self.handle.connect(res[4])
60 except socket.error, e:
61 if res is not res0[-1]:
62 continue
63 else:
64 raise e
65 break
Mark Slee92195ae2007-02-21 05:16:30 +000066 except socket.error, e:
Mark Slee76791962007-03-14 02:47:35 +000067 raise TTransportException(TTransportException.NOT_OPEN, 'Could not connect to %s:%d' % (self.host, self.port))
Mark Sleecde2b612006-09-03 21:13:07 +000068
69 def close(self):
Mark Sleed788b2e2006-09-07 01:26:35 +000070 if self.handle != None:
71 self.handle.close()
72 self.handle = None
Mark Sleecde2b612006-09-03 21:13:07 +000073
Mark Sleecde2b612006-09-03 21:13:07 +000074 def read(self, sz):
75 buff = self.handle.recv(sz)
Mark Sleec9676562006-09-05 17:34:52 +000076 if len(buff) == 0:
Mark Slee4f0fed62006-10-02 17:50:08 +000077 raise TTransportException('TSocket read 0 bytes')
Mark Sleecde2b612006-09-03 21:13:07 +000078 return buff
79
80 def write(self, buff):
Mark Sleec9676562006-09-05 17:34:52 +000081 sent = 0
82 have = len(buff)
83 while sent < have:
84 plus = self.handle.send(buff)
85 if plus == 0:
Mark Slee92195ae2007-02-21 05:16:30 +000086 raise TTransportException('TSocket sent 0 bytes')
Mark Sleec9676562006-09-05 17:34:52 +000087 sent += plus
88 buff = buff[plus:]
Mark Sleecde2b612006-09-03 21:13:07 +000089
90 def flush(self):
91 pass
Mark Sleec9676562006-09-05 17:34:52 +000092
93class TServerSocket(TServerTransportBase):
94
95 """Socket implementation of TServerTransport base."""
96
97 def __init__(self, port):
98 self.port = port
99 self.handle = None
Mark Slee256bdc42007-11-27 08:42:19 +0000100
Mark Sleec9676562006-09-05 17:34:52 +0000101 def listen(self):
Mark Slee256bdc42007-11-27 08:42:19 +0000102 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 +0000103 for res in res0:
104 if res[0] is socket.AF_INET6 or res is res0[-1]:
105 break
106
107 self.handle = socket.socket(res[0], res[1])
Mark Slee4f0fed62006-10-02 17:50:08 +0000108 self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
109 if hasattr(self.handle, 'set_timeout'):
110 self.handle.set_timeout(None)
Mark Slee22974602007-07-06 22:20:19 +0000111 self.handle.bind(res[4])
Mark Sleec9676562006-09-05 17:34:52 +0000112 self.handle.listen(128)
113
114 def accept(self):
115 (client, addr) = self.handle.accept()
116 result = TSocket()
Mark Slee4f0fed62006-10-02 17:50:08 +0000117 result.setHandle(client)
Mark Sleec9676562006-09-05 17:34:52 +0000118 return result
119
120 def close(self):
121 self.handle.close()
122 self.handle = None