blob: 67faa51025b62c5efd9455ccda534d522557a0bd [file] [log] [blame]
Mark Slee254ce202007-05-16 02:21:06 +00001#
David Reissea2cba82009-03-30 21:35:00 +00002# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
Mark Slee254ce202007-05-16 02:21:06 +00009#
David Reissea2cba82009-03-30 21:35:00 +000010# http://www.apache.org/licenses/LICENSE-2.0
Mark Slee254ce202007-05-16 02:21:06 +000011#
David Reissea2cba82009-03-30 21:35:00 +000012# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
Mark Slee254ce202007-05-16 02:21:06 +000018#
19
20require 5.6.0;
21use strict;
22use warnings;
23
24use Thrift;
25use Thrift::Transport;
26
27use IO::Socket::INET;
28use IO::Select;
29
30package Thrift::Socket;
31
32use base('Thrift::Transport');
33
34sub new
35{
36 my $classname = shift;
37 my $host = shift || "localhost";
38 my $port = shift || 9090;
39 my $debugHandler = shift;
40
41 my $self = {
42 host => $host,
43 port => $port,
44 debugHandler => $debugHandler,
45 debug => 0,
46 sendTimeout => 100,
47 recvTimeout => 750,
48 handle => undef,
49 };
50
51 return bless($self,$classname);
52}
53
54
55sub setSendTimeout
56{
57 my $self = shift;
58 my $timeout = shift;
59
60 $self->{sendTimeout} = $timeout;
61}
62
63sub setRecvTimeout
64{
65 my $self = shift;
66 my $timeout = shift;
67
68 $self->{recvTimeout} = $timeout;
69}
70
71
72#
73#Sets debugging output on or off
74#
75# @param bool $debug
76#
77sub setDebug
78{
79 my $self = shift;
80 my $debug = shift;
81
82 $self->{debug} = $debug;
83}
84
85#
86# Tests whether this is open
87#
88# @return bool true if the socket is open
89#
90sub isOpen
91{
92 my $self = shift;
93
T Jake Luciani0d738892008-12-23 03:12:50 +000094 if( defined $self->{handle} ){
95 return ($self->{handle}->handles())[0]->connected;
96 }
97
98 return 0;
Mark Slee254ce202007-05-16 02:21:06 +000099}
100
101#
102# Connects the socket.
103#
104sub open
105{
106 my $self = shift;
107
108 my $sock = IO::Socket::INET->new(PeerAddr => $self->{host},
109 PeerPort => $self->{port},
110 Proto => 'tcp',
111 Timeout => $self->{sendTimeout}/1000)
112 || do {
113 my $error = 'TSocket: Could not connect to '.$self->{host}.':'.$self->{port}.' ('.$!.')';
114
115 if ($self->{debug}) {
116 $self->{debugHandler}->($error);
117 }
118
119 die new Thrift::TException($error);
120
121 };
122
123
124 $self->{handle} = new IO::Select( $sock );
125}
126
127#
128# Closes the socket.
129#
130sub close
131{
132 my $self = shift;
133
T Jake Luciani0d738892008-12-23 03:12:50 +0000134 if( defined $self->{handle} ){
135 close( ($self->{handle}->handles())[0] );
136 }
Mark Slee254ce202007-05-16 02:21:06 +0000137}
138
139#
140# Uses stream get contents to do the reading
141#
142# @param int $len How many bytes
143# @return string Binary data
144#
145sub readAll
146{
147 my $self = shift;
148 my $len = shift;
149
150
T Jake Luciani0d738892008-12-23 03:12:50 +0000151 return unless defined $self->{handle};
152
Mark Slee254ce202007-05-16 02:21:06 +0000153 my $pre = "";
154 while (1) {
155
156 #check for timeout
David Reiss7502e0b2008-03-27 19:45:24 +0000157 my @sockets = $self->{handle}->can_read( $self->{recvTimeout} / 1000 );
Mark Slee254ce202007-05-16 02:21:06 +0000158
159 if(@sockets == 0){
160 die new Thrift::TException('TSocket: timed out reading '.$len.' bytes from '.
161 $self->{host}.':'.$self->{port});
162 }
163
164 my $sock = $sockets[0];
165
166 my ($buf,$sz);
167 $sock->recv($buf, $len);
168
169 if (!defined $buf || $buf eq '') {
170
171 die new Thrift::TException('TSocket: Could not read '.$len.' bytes from '.
172 $self->{host}.':'.$self->{port});
173
174 } elsif (($sz = length($buf)) < $len) {
175
176 $pre .= $buf;
177 $len -= $sz;
178
179 } else {
180 return $pre.$buf;
181 }
182 }
183}
184
185#
186# Read from the socket
187#
188# @param int $len How many bytes
189# @return string Binary data
190#
191sub read
192{
193 my $self = shift;
194 my $len = shift;
195
T Jake Luciani0d738892008-12-23 03:12:50 +0000196 return unless defined $self->{handle};
197
Mark Slee254ce202007-05-16 02:21:06 +0000198 #check for timeout
David Reiss7502e0b2008-03-27 19:45:24 +0000199 my @sockets = $self->{handle}->can_read( $self->{sendTimeout} / 1000 );
Mark Slee254ce202007-05-16 02:21:06 +0000200
201 if(@sockets == 0){
202 die new Thrift::TException('TSocket: timed out reading '.$len.' bytes from '.
203 $self->{host}.':'.$self->{port});
204 }
205
206 my $sock = $sockets[0];
207
208 my ($buf,$sz);
209 $sock->recv($buf, $len);
210
211 if (!defined $buf || $buf eq '') {
212
213 die new TException('TSocket: Could not read '.$len.' bytes from '.
214 $self->{host}.':'.$self->{port});
215
216 }
217
218 return $buf;
219}
220
221
222#
223# Write to the socket.
224#
225# @param string $buf The data to write
226#
227sub write
228{
229 my $self = shift;
230 my $buf = shift;
231
232
T Jake Luciani0d738892008-12-23 03:12:50 +0000233 return unless defined $self->{handle};
234
Mark Slee254ce202007-05-16 02:21:06 +0000235 while (length($buf) > 0) {
236
237
238 #check for timeout
David Reiss7502e0b2008-03-27 19:45:24 +0000239 my @sockets = $self->{handle}->can_write( $self->{recvTimeout} / 1000 );
Mark Slee254ce202007-05-16 02:21:06 +0000240
241 if(@sockets == 0){
242 die new Thrift::TException('TSocket: timed out writing to bytes from '.
243 $self->{host}.':'.$self->{port});
244 }
245
246 my $sock = $sockets[0];
247
248 my $got = $sock->send($buf);
249
250 if (!defined $got || $got == 0 ) {
T Jake Luciani6b407112009-03-02 23:47:20 +0000251 die new Thrift::TException('TSocket: Could not write '.length($buf).' bytes '.
Mark Slee254ce202007-05-16 02:21:06 +0000252 $self->{host}.':'.$self->{host});
253 }
254
255 $buf = substr($buf, $got);
256 }
257}
258
259#
260# Flush output to the socket.
261#
262sub flush
263{
264 my $self = shift;
T Jake Luciani0d738892008-12-23 03:12:50 +0000265
266 return unless defined $self->{handle};
267
Mark Slee254ce202007-05-16 02:21:06 +0000268 my $ret = ($self->{handle}->handles())[0]->flush;
269}
270
2711;