blob: 2c17e436b090df5e0b95663f895e8749835ed6b7 [file] [log] [blame]
Mark Slee7eb0d632007-03-01 00:00:27 +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 Slee83c52a82006-06-07 06:51:18 +00007package com.facebook.thrift.transport;
8
9import java.io.BufferedInputStream;
10import java.io.BufferedOutputStream;
11import java.io.IOException;
12import java.net.InetSocketAddress;
13import java.net.Socket;
Mark Slee5bcde6e2006-09-27 17:50:32 +000014import java.net.SocketException;
Mark Slee83c52a82006-06-07 06:51:18 +000015
16/**
17 * Socket implementation of the TTransport interface. To be commented soon!
18 *
19 * @author Mark Slee <mcslee@facebook.com>
20 */
21public class TSocket extends TIOStreamTransport {
22
Mark Slee5bcde6e2006-09-27 17:50:32 +000023 /**
24 * Wrapped Socket object
25 */
Mark Slee83c52a82006-06-07 06:51:18 +000026 private Socket socket_ = null;
27
Mark Slee5bcde6e2006-09-27 17:50:32 +000028 /**
29 * Remote host
30 */
Mark Slee83c52a82006-06-07 06:51:18 +000031 private String host_ = null;
32
Mark Slee5bcde6e2006-09-27 17:50:32 +000033 /**
34 * Remote port
35 */
Mark Slee83c52a82006-06-07 06:51:18 +000036 private int port_ = 0;
37
38 /**
Mark Slee5bcde6e2006-09-27 17:50:32 +000039 * Socket timeout
40 */
41 private int timeout_ = 0;
42
43 /**
Mark Slee83c52a82006-06-07 06:51:18 +000044 * Constructor that takes an already created socket.
45 *
46 * @param socket Already created socket object
47 * @throws TTransportException if there is an error setting up the streams
48 */
49 public TSocket(Socket socket) throws TTransportException {
50 socket_ = socket;
Mark Slee845fe3d2006-09-27 20:51:11 +000051 try {
52 socket_.setSoLinger(false, 0);
53 socket_.setTcpNoDelay(true);
54 } catch (SocketException sx) {
55 sx.printStackTrace();
56 }
57
Mark Slee83c52a82006-06-07 06:51:18 +000058 if (isOpen()) {
59 try {
Mark Slee530fd662006-08-09 00:05:18 +000060 inputStream_ = new BufferedInputStream(socket_.getInputStream(), 1024);
61 outputStream_ = new BufferedOutputStream(socket_.getOutputStream(), 1024);
Mark Slee83c52a82006-06-07 06:51:18 +000062 } catch (IOException iox) {
63 close();
Mark Sleeb46c0412007-02-21 04:54:38 +000064 throw new TTransportException(TTransportException.NOT_OPEN, iox);
Mark Slee83c52a82006-06-07 06:51:18 +000065 }
66 }
67 }
68
69 /**
70 * Creates a new unconnected socket that will connect to the given host
71 * on the given port.
72 *
73 * @param host Remote host
74 * @param port Remote port
75 */
76 public TSocket(String host, int port) {
Mark Slee845fe3d2006-09-27 20:51:11 +000077 this(host, port, 0);
Mark Slee5bcde6e2006-09-27 17:50:32 +000078 }
79
80 /**
81 * Creates a new unconnected socket that will connect to the given host
82 * on the given port.
83 *
84 * @param host Remote host
85 * @param port Remote port
86 * @param timeout Socket timeout
87 */
88 public TSocket(String host, int port, int timeout) {
Mark Slee83c52a82006-06-07 06:51:18 +000089 host_ = host;
90 port_ = port;
Mark Slee5bcde6e2006-09-27 17:50:32 +000091 timeout_ = timeout;
Mark Slee845fe3d2006-09-27 20:51:11 +000092 initSocket();
93 }
94
95 /**
96 * Initializes the socket object
97 */
98 private void initSocket() {
99 socket_ = new Socket();
100 try {
101 socket_.setSoLinger(false, 0);
102 socket_.setTcpNoDelay(true);
103 socket_.setSoTimeout(timeout_);
104 } catch (SocketException sx) {
105 sx.printStackTrace();
106 }
Mark Slee5bcde6e2006-09-27 17:50:32 +0000107 }
108
109 /**
110 * Sets the socket timeout
111 *
112 * @param timeout Milliseconds timeout
113 */
114 public void setTimeout(int timeout) {
115 timeout_ = timeout;
116 try {
117 socket_.setSoTimeout(timeout);
118 } catch (SocketException sx) {
119 sx.printStackTrace();
120 }
Mark Slee83c52a82006-06-07 06:51:18 +0000121 }
122
123 /**
Mark Slee845fe3d2006-09-27 20:51:11 +0000124 * Returns a reference to the underlying socket.
Mark Slee83c52a82006-06-07 06:51:18 +0000125 */
126 public Socket getSocket() {
127 if (socket_ == null) {
Mark Slee845fe3d2006-09-27 20:51:11 +0000128 initSocket();
Mark Slee83c52a82006-06-07 06:51:18 +0000129 }
130 return socket_;
131 }
132
133 /**
134 * Checks whether the socket is connected.
135 */
136 public boolean isOpen() {
137 if (socket_ == null) {
138 return false;
139 }
140 return socket_.isConnected();
141 }
142
143 /**
144 * Connects the socket, creating a new socket object if necessary.
145 */
146 public void open() throws TTransportException {
Mark Slee83c52a82006-06-07 06:51:18 +0000147 if (isOpen()) {
Mark Sleeb46c0412007-02-21 04:54:38 +0000148 throw new TTransportException(TTransportException.ALREADY_OPEN, "Socket already connected.");
Mark Slee83c52a82006-06-07 06:51:18 +0000149 }
150
Mark Slee845fe3d2006-09-27 20:51:11 +0000151 if (host_.length() == 0) {
Mark Sleeb46c0412007-02-21 04:54:38 +0000152 throw new TTransportException(TTransportException.NOT_OPEN, "Cannot open null host.");
Mark Slee845fe3d2006-09-27 20:51:11 +0000153 }
154 if (port_ <= 0) {
Mark Sleeb46c0412007-02-21 04:54:38 +0000155 throw new TTransportException(TTransportException.NOT_OPEN, "Cannot open without port.");
Mark Slee845fe3d2006-09-27 20:51:11 +0000156 }
157
158 if (socket_ == null) {
159 initSocket();
160 }
161
Mark Slee83c52a82006-06-07 06:51:18 +0000162 try {
163 socket_.connect(new InetSocketAddress(host_, port_));
Mark Slee530fd662006-08-09 00:05:18 +0000164 inputStream_ = new BufferedInputStream(socket_.getInputStream(), 1024);
165 outputStream_ = new BufferedOutputStream(socket_.getOutputStream(), 1024);
Mark Slee83c52a82006-06-07 06:51:18 +0000166 } catch (IOException iox) {
167 close();
Mark Sleeb46c0412007-02-21 04:54:38 +0000168 throw new TTransportException(TTransportException.NOT_OPEN, iox);
Mark Slee83c52a82006-06-07 06:51:18 +0000169 }
170 }
171
172 /**
173 * Closes the socket.
174 */
175 public void close() {
176 // Close the underlying streams
177 super.close();
178
179 // Close the socket
180 if (socket_ != null) {
181 try {
182 socket_.close();
183 } catch (IOException iox) {
184 System.err.println("WARNING: exception closing socket: " +
185 iox.getMessage());
186 }
187 socket_ = null;
188 }
189 }
190
191}