/protocols/smpp/src/main/java/org/mobicents/protocols/smpp/net/TcpLink.java
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 23package org.mobicents.protocols.smpp.net; 24 25import java.io.BufferedInputStream; 26import java.io.BufferedOutputStream; 27import java.io.IOException; 28import java.io.InputStream; 29import java.io.OutputStream; 30import java.net.InetAddress; 31import java.net.InetSocketAddress; 32import java.net.Socket; 33import java.net.SocketAddress; 34import java.net.SocketException; 35 36import org.slf4j.Logger; 37import org.slf4j.LoggerFactory; 38 39/** 40 * Implementation of an Smsc link over the tcp/ip protocol 41 * 42 * @version $Id: TcpLink.java 452 2009-01-15 16:56:36Z orank $ 43 * @author amit bhayani 44 * @author orank 45 */ 46public class TcpLink extends AbstractStreamLink { 47 private static final String STACK_TRACE_ERR = "Stack trace:"; 48 49 private static final String SOCKET_NOT_OPEN_ERR = "Socket connection is not open"; 50 51 private static final Logger LOG = LoggerFactory.getLogger(TcpLink.class); 52 53 /** 54 * Default IP port to use if none are specified. 55 */ 56 public static final int DEFAULT_PORT = 5016; 57 58 /** 59 * The internet address of the SMSC. 60 */ 61 private InetAddress addr; 62 63 /** 64 * The port to connect to. 65 */ 66 private int port; 67 68 /** 69 * The socket timeout setting. 70 */ 71 private int sockTimeout; 72 73 private Socket sock; 74 75 /** 76 * Create a new TcpLink 77 * 78 * @param address 79 * IP address or hostname of SMSC 80 * @throws java.net.UnknownHostException 81 * If the host is not found. 82 */ 83 public TcpLink(String address) throws java.net.UnknownHostException { 84 this(address, DEFAULT_PORT); 85 } 86 87 /** 88 * Create a new TcpLink 89 * 90 * @param address 91 * IP address or hostname of SMSC 92 * @param port 93 * The port number to connect to 94 * @throws java.net.UnknownHostException 95 * If the host is not found. 96 */ 97 public TcpLink(String address, int port) throws java.net.UnknownHostException { 98 this.addr = InetAddress.getByName(address); 99 if (port < 1) { 100 this.port = DEFAULT_PORT; 101 } else { 102 this.port = port; 103 } 104 } 105 106 /** 107 * Create a new TcpLink 108 * 109 * @param address 110 * IP address SMSC 111 * @throws java.net.UnknownHostException 112 * If the host is not found. 113 */ 114 public TcpLink(InetAddress address) { 115 this(address, DEFAULT_PORT); 116 } 117 118 /** 119 * Create a new TcpLink 120 * 121 * @param address 122 * IP address of SMSC 123 * @param port 124 * The port number to connect to 125 * @throws java.net.UnknownHostException 126 * If the host is not found. 127 */ 128 public TcpLink(InetAddress address, int port) { 129 this.addr = address; 130 if (port < 1) { 131 this.port = DEFAULT_PORT; 132 } else { 133 this.port = port; 134 } 135 } 136 137 /** 138 * Create a new TcpLink object around an existing socket. 139 * @param socket The socket to use for communications. 140 */ 141 public TcpLink(Socket socket) throws IOException { 142 this.sock = socket; 143 setInputStream(sock.getInputStream()); 144 setOutputStream(sock.getOutputStream()); 145 } 146 147 /** 148 * Get the address we're connected (or connecting) to. 149 * 150 * @return The address of the SMSC this link is connected to. 151 */ 152 public InetAddress getAddress() { 153 return addr; 154 } 155 156 /** 157 * Get the service port to connect to at the SMSC to establish a TCP 158 * connection. 159 * 160 * @return The service port at the SMSC to connect to. 161 */ 162 public int getPort() { 163 return port; 164 } 165 166 /** 167 * Get the port at the SMSC that this link is connected to. This is the 168 * remote port that this link is connected to after a successful connection 169 * has been made. 170 * 171 * @return The remote port this link is connected to. 172 * @throws java.io.IOException 173 * If the connection is not open. 174 */ 175 public int getConnectedPort() throws java.io.IOException { 176 if (sock == null) { 177 throw new IOException(SOCKET_NOT_OPEN_ERR); 178 } else { 179 return sock.getPort(); 180 } 181 } 182 183 /** 184 * Get the local port number this link is connected to. 185 * 186 * @return The local port number this link is connected to. 187 * @throws java.io.IOException 188 * If the connection is not open. 189 */ 190 public int getLocalPort() throws java.io.IOException { 191 if (sock == null) { 192 throw new IOException(SOCKET_NOT_OPEN_ERR); 193 } else { 194 return sock.getLocalPort(); 195 } 196 } 197 198 public boolean isConnected() { 199 return sock != null && sock.isConnected(); 200 } 201 202 /** 203 * Set the socket timeout. This SmscLink implementation uses SO_TIMEOUT 204 * to implement read timeouts. 205 * @param timeout The timeout to set. 206 * @see SmscLink#setTimeout(int) 207 */ 208 public void setTimeout(int timeout) { 209 try { 210 sockTimeout = timeout; 211 if (sock != null) { 212 sock.setSoTimeout(sockTimeout); 213 } 214 } catch (SocketException x) { 215 LOG.error("Failed to set timeout on socket: {} ", x.getMessage()); 216 if (LOG.isDebugEnabled()) { 217 LOG.debug(STACK_TRACE_ERR, x); 218 } 219 } 220 } 221 222 public int getTimeout() { 223 try { 224 return sock.getSoTimeout(); 225 } catch (SocketException x) { 226 if (LOG.isDebugEnabled()) { 227 LOG.debug(STACK_TRACE_ERR, x); 228 } 229 } 230 return -1; 231 } 232 233 public boolean isTimeoutSupported() { 234 return true; 235 } 236 237 public void connect() throws java.io.IOException { 238 if (sock != null) { 239 LOG.debug("Cannot connect a link wrapped around a socket."); 240 throw new IllegalStateException(); 241 } 242 LOG.info("Opening TCP socket to {}:{}", addr, port); 243 this.sock = new Socket(); 244 SocketAddress sockAddr = new InetSocketAddress(addr, port); 245 this.sock.connect(sockAddr, sockTimeout); 246 if (sockTimeout > 0) { 247 LOG.info("Set Socket Timeout to {}", sockTimeout); 248 sock.setSoTimeout(sockTimeout); 249 } 250 251 setInputStream(new BufferedInputStream(sock.getInputStream())); 252 setOutputStream(new BufferedOutputStream(sock.getOutputStream())); 253 } 254 255 public void disconnect() throws java.io.IOException { 256 if (isConnected()) { 257 LOG.info("Shutting down socket connection"); 258 sock.close(); 259 sock = null; 260 } 261 } 262 263 /** 264 * Get the output stream of the Socket connection to the SMSC. 265 * 266 * @throws java.io.IOException 267 * If the socket connection is not open or an I/O error occurs 268 * when creating the output stream. 269 * @see java.io.OutputStream 270 * @see java.net.Socket#getOutputStream 271 */ 272 protected OutputStream getOutputStream() throws java.io.IOException { 273 if (sock == null) { 274 throw new IOException(SOCKET_NOT_OPEN_ERR); 275 } else { 276 return sock.getOutputStream(); 277 } 278 } 279 280 /** 281 * Get the input stream of the Socket connection to the SMSC. 282 * 283 * @throws java.io.IOException 284 * If the socket connection is not open or an I/O error occurs 285 * when creating the input stream. 286 * @see java.io.InputStream 287 * @see java.net.Socket#getInputStream 288 */ 289 protected InputStream getInputStream() throws java.io.IOException { 290 if (sock == null) { 291 throw new IOException(SOCKET_NOT_OPEN_ERR); 292 } else { 293 return sock.getInputStream(); 294 } 295 } 296}