/protocols/smpp/src/main/java/org/mobicents/protocols/smpp/net/TcpLink.java

http://mobicents.googlecode.com/ · Java · 296 lines · 136 code · 29 blank · 131 comment · 26 complexity · ee42b721640c531983bef98b16b288bf MD5 · raw file

  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2011, Red Hat, Inc. and individual contributors
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.mobicents.protocols.smpp.net;
  23. import java.io.BufferedInputStream;
  24. import java.io.BufferedOutputStream;
  25. import java.io.IOException;
  26. import java.io.InputStream;
  27. import java.io.OutputStream;
  28. import java.net.InetAddress;
  29. import java.net.InetSocketAddress;
  30. import java.net.Socket;
  31. import java.net.SocketAddress;
  32. import java.net.SocketException;
  33. import org.slf4j.Logger;
  34. import org.slf4j.LoggerFactory;
  35. /**
  36. * Implementation of an Smsc link over the tcp/ip protocol
  37. *
  38. * @version $Id: TcpLink.java 452 2009-01-15 16:56:36Z orank $
  39. * @author amit bhayani
  40. * @author orank
  41. */
  42. public class TcpLink extends AbstractStreamLink {
  43. private static final String STACK_TRACE_ERR = "Stack trace:";
  44. private static final String SOCKET_NOT_OPEN_ERR = "Socket connection is not open";
  45. private static final Logger LOG = LoggerFactory.getLogger(TcpLink.class);
  46. /**
  47. * Default IP port to use if none are specified.
  48. */
  49. public static final int DEFAULT_PORT = 5016;
  50. /**
  51. * The internet address of the SMSC.
  52. */
  53. private InetAddress addr;
  54. /**
  55. * The port to connect to.
  56. */
  57. private int port;
  58. /**
  59. * The socket timeout setting.
  60. */
  61. private int sockTimeout;
  62. private Socket sock;
  63. /**
  64. * Create a new TcpLink
  65. *
  66. * @param address
  67. * IP address or hostname of SMSC
  68. * @throws java.net.UnknownHostException
  69. * If the host is not found.
  70. */
  71. public TcpLink(String address) throws java.net.UnknownHostException {
  72. this(address, DEFAULT_PORT);
  73. }
  74. /**
  75. * Create a new TcpLink
  76. *
  77. * @param address
  78. * IP address or hostname of SMSC
  79. * @param port
  80. * The port number to connect to
  81. * @throws java.net.UnknownHostException
  82. * If the host is not found.
  83. */
  84. public TcpLink(String address, int port) throws java.net.UnknownHostException {
  85. this.addr = InetAddress.getByName(address);
  86. if (port < 1) {
  87. this.port = DEFAULT_PORT;
  88. } else {
  89. this.port = port;
  90. }
  91. }
  92. /**
  93. * Create a new TcpLink
  94. *
  95. * @param address
  96. * IP address SMSC
  97. * @throws java.net.UnknownHostException
  98. * If the host is not found.
  99. */
  100. public TcpLink(InetAddress address) {
  101. this(address, DEFAULT_PORT);
  102. }
  103. /**
  104. * Create a new TcpLink
  105. *
  106. * @param address
  107. * IP address of SMSC
  108. * @param port
  109. * The port number to connect to
  110. * @throws java.net.UnknownHostException
  111. * If the host is not found.
  112. */
  113. public TcpLink(InetAddress address, int port) {
  114. this.addr = address;
  115. if (port < 1) {
  116. this.port = DEFAULT_PORT;
  117. } else {
  118. this.port = port;
  119. }
  120. }
  121. /**
  122. * Create a new TcpLink object around an existing socket.
  123. * @param socket The socket to use for communications.
  124. */
  125. public TcpLink(Socket socket) throws IOException {
  126. this.sock = socket;
  127. setInputStream(sock.getInputStream());
  128. setOutputStream(sock.getOutputStream());
  129. }
  130. /**
  131. * Get the address we're connected (or connecting) to.
  132. *
  133. * @return The address of the SMSC this link is connected to.
  134. */
  135. public InetAddress getAddress() {
  136. return addr;
  137. }
  138. /**
  139. * Get the service port to connect to at the SMSC to establish a TCP
  140. * connection.
  141. *
  142. * @return The service port at the SMSC to connect to.
  143. */
  144. public int getPort() {
  145. return port;
  146. }
  147. /**
  148. * Get the port at the SMSC that this link is connected to. This is the
  149. * remote port that this link is connected to after a successful connection
  150. * has been made.
  151. *
  152. * @return The remote port this link is connected to.
  153. * @throws java.io.IOException
  154. * If the connection is not open.
  155. */
  156. public int getConnectedPort() throws java.io.IOException {
  157. if (sock == null) {
  158. throw new IOException(SOCKET_NOT_OPEN_ERR);
  159. } else {
  160. return sock.getPort();
  161. }
  162. }
  163. /**
  164. * Get the local port number this link is connected to.
  165. *
  166. * @return The local port number this link is connected to.
  167. * @throws java.io.IOException
  168. * If the connection is not open.
  169. */
  170. public int getLocalPort() throws java.io.IOException {
  171. if (sock == null) {
  172. throw new IOException(SOCKET_NOT_OPEN_ERR);
  173. } else {
  174. return sock.getLocalPort();
  175. }
  176. }
  177. public boolean isConnected() {
  178. return sock != null && sock.isConnected();
  179. }
  180. /**
  181. * Set the socket timeout. This SmscLink implementation uses SO_TIMEOUT
  182. * to implement read timeouts.
  183. * @param timeout The timeout to set.
  184. * @see SmscLink#setTimeout(int)
  185. */
  186. public void setTimeout(int timeout) {
  187. try {
  188. sockTimeout = timeout;
  189. if (sock != null) {
  190. sock.setSoTimeout(sockTimeout);
  191. }
  192. } catch (SocketException x) {
  193. LOG.error("Failed to set timeout on socket: {} ", x.getMessage());
  194. if (LOG.isDebugEnabled()) {
  195. LOG.debug(STACK_TRACE_ERR, x);
  196. }
  197. }
  198. }
  199. public int getTimeout() {
  200. try {
  201. return sock.getSoTimeout();
  202. } catch (SocketException x) {
  203. if (LOG.isDebugEnabled()) {
  204. LOG.debug(STACK_TRACE_ERR, x);
  205. }
  206. }
  207. return -1;
  208. }
  209. public boolean isTimeoutSupported() {
  210. return true;
  211. }
  212. public void connect() throws java.io.IOException {
  213. if (sock != null) {
  214. LOG.debug("Cannot connect a link wrapped around a socket.");
  215. throw new IllegalStateException();
  216. }
  217. LOG.info("Opening TCP socket to {}:{}", addr, port);
  218. this.sock = new Socket();
  219. SocketAddress sockAddr = new InetSocketAddress(addr, port);
  220. this.sock.connect(sockAddr, sockTimeout);
  221. if (sockTimeout > 0) {
  222. LOG.info("Set Socket Timeout to {}", sockTimeout);
  223. sock.setSoTimeout(sockTimeout);
  224. }
  225. setInputStream(new BufferedInputStream(sock.getInputStream()));
  226. setOutputStream(new BufferedOutputStream(sock.getOutputStream()));
  227. }
  228. public void disconnect() throws java.io.IOException {
  229. if (isConnected()) {
  230. LOG.info("Shutting down socket connection");
  231. sock.close();
  232. sock = null;
  233. }
  234. }
  235. /**
  236. * Get the output stream of the Socket connection to the SMSC.
  237. *
  238. * @throws java.io.IOException
  239. * If the socket connection is not open or an I/O error occurs
  240. * when creating the output stream.
  241. * @see java.io.OutputStream
  242. * @see java.net.Socket#getOutputStream
  243. */
  244. protected OutputStream getOutputStream() throws java.io.IOException {
  245. if (sock == null) {
  246. throw new IOException(SOCKET_NOT_OPEN_ERR);
  247. } else {
  248. return sock.getOutputStream();
  249. }
  250. }
  251. /**
  252. * Get the input stream of the Socket connection to the SMSC.
  253. *
  254. * @throws java.io.IOException
  255. * If the socket connection is not open or an I/O error occurs
  256. * when creating the input stream.
  257. * @see java.io.InputStream
  258. * @see java.net.Socket#getInputStream
  259. */
  260. protected InputStream getInputStream() throws java.io.IOException {
  261. if (sock == null) {
  262. throw new IOException(SOCKET_NOT_OPEN_ERR);
  263. } else {
  264. return sock.getInputStream();
  265. }
  266. }
  267. }