View Javadoc
1   // NAME
2   //      $RCSfile: TCPSocket.java,v $
3   // DESCRIPTION
4   //      [given below in javadoc format]
5   // DELTA
6   //      $Revision: 1.8 $
7   // CREATED
8   //      $Date: 2009/03/05 15:56:19 $
9   // COPYRIGHT
10  //      Westhawk Ltd
11  // TO DO
12  //
13  
14  /*
15   * Copyright (C) 2005 - 2006 by Westhawk Ltd
16   * <a href="www.westhawk.co.uk">www.westhawk.co.uk</a>
17   *
18   * Permission to use, copy, modify, and distribute this software
19   * for any purpose and without fee is hereby granted, provided
20   * that the above copyright notices appear in all copies and that
21   * both the copyright notice and this permission notice appear in
22   * supporting documentation.
23   * This software is provided "as is" without express or implied
24   * warranty.
25   * author <a href="mailto:snmp@westhawk.co.uk">Tim Panton</a>
26   */
27  
28  package uk.co.westhawk.snmp.net;
29  
30  /*-
31   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
32   * SNMP Java Client
33   * ჻჻჻჻჻჻
34   * Copyright 2023 MetricsHub, Westhawk
35   * ჻჻჻჻჻჻
36   * This program is free software: you can redistribute it and/or modify
37   * it under the terms of the GNU Lesser General Public License as
38   * published by the Free Software Foundation, either version 3 of the
39   * License, or (at your option) any later version.
40   *
41   * This program is distributed in the hope that it will be useful,
42   * but WITHOUT ANY WARRANTY; without even the implied warranty of
43   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
44   * GNU General Lesser Public License for more details.
45   *
46   * You should have received a copy of the GNU General Lesser Public
47   * License along with this program.  If not, see
48   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
49   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
50   */
51  
52  import java.io.*;
53  import java.net.*;
54  import uk.co.westhawk.snmp.stack.*;
55  
56  /**
57   * This is a wrapper class around the standard Socket. This sends
58   * packets over TCP.  
59   *
60   * <p>
61   * This is part of what is called "Reliable SNMP". SNMP usually goes
62   * over UDP. That is why there is a retry mechanisme in SNMP. Sending
63   * SNMP over TCP will only work is your agent listens on TCP.
64   * See
65   * <a href="http://www.ietf.org/rfc/rfc3430.txt">RFC 3430</a>
66   * </p>
67   *
68   * <p>
69   * When listening for incoming packets, the Socket, that is created when
70   * accepting an incoming connection, is closed at the end.
71   * Because of this, it is NOT possible to send a response back over the
72   * same connection.
73   * </p>
74   *
75   * @see Socket
76   * @since 4_14
77   * @author <a href="mailto:snmp@westhawk.co.uk">Birgit Arkesteijn</a>
78   * @version $Revision: 1.8 $ $Date: 2009/03/05 15:56:19 $
79   */
80  public class TCPSocket implements ContextSocketFace {
81      static final String version_id = "@(#)$Id: TCPSocket.java,v 1.8 2009/03/05 15:56:19 birgita Exp $ Copyright Westhawk Ltd";
82  
83      private ServerSocket serverSoc = null;
84      private Socket clientSoc = null;
85      private InetAddress sendToHostAddr;
86      private int sendToHostPort;
87      private InetAddress receiveFromHostAddr;
88      private int receiveFromHostPort;
89      private InetAddress locBindAddr;
90  
91      public TCPSocket() {
92      }
93  
94      public void create(int port, String bindAddr) throws IOException {
95          sendToHostPort = port;
96          receiveFromHostPort = sendToHostPort; // initialise (once!)
97          try {
98              locBindAddr = null;
99              if (bindAddr != null) {
100                 locBindAddr = InetAddress.getByName(bindAddr);
101             }
102             serverSoc = new ServerSocket(sendToHostPort, 50, locBindAddr);
103         } catch (SocketException exc) {
104             String str = "Socket problem: port=" + port + ", bindAddr="
105                     + bindAddr + " " + exc.getMessage();
106             throw (new IOException(str));
107         }
108     }
109 
110     public void create(String host, int port, String bindAddr) throws IOException {
111         sendToHostPort = port;
112         receiveFromHostPort = sendToHostPort; // initialise (once!)
113         try {
114             sendToHostAddr = InetAddress.getByName(host);
115             receiveFromHostAddr = sendToHostAddr; // initialise (once!)
116             locBindAddr = null;
117             if (bindAddr != null) {
118                 locBindAddr = InetAddress.getByName(bindAddr);
119             }
120             clientSoc = new Socket(sendToHostAddr, sendToHostPort, locBindAddr, 0);
121         } catch (SocketException exc) {
122             String str = "Socket problem: host=" + host + ", port=" + port
123                     + ", bindAddr=" + bindAddr + " " + exc.getMessage();
124             throw (new IOException(str));
125         } catch (UnknownHostException exc) {
126             String str = "Cannot find host " + host + " " + exc.getMessage();
127             throw (new IOException(str));
128         }
129     }
130 
131     public String getReceivedFromHostAddress() {
132         String res = null;
133         if (receiveFromHostAddr != null) {
134             res = receiveFromHostAddr.getHostAddress();
135         }
136         return res;
137     }
138 
139     public String getSendToHostAddress() {
140         String res = null;
141         if (sendToHostAddr != null) {
142             res = sendToHostAddr.getHostAddress();
143         }
144         return res;
145     }
146 
147     public String getLocalSocketAddress() {
148         String res = null;
149         if (serverSoc != null) {
150             SocketAddress sa = serverSoc.getLocalSocketAddress();
151             if (sa != null) {
152                 res = sa.toString();
153             }
154         } else if (clientSoc != null) {
155             SocketAddress sa = clientSoc.getLocalSocketAddress();
156             if (sa != null) {
157                 res = sa.toString();
158             }
159         }
160         return res;
161     }
162 
163     public String getRemoteSocketAddress() {
164         String res = null;
165         if (clientSoc != null) {
166             SocketAddress sa = clientSoc.getRemoteSocketAddress();
167             if (sa != null) {
168                 res = sa.toString();
169             }
170         } else if (serverSoc != null) {
171             //
172         }
173         return res;
174     }
175 
176     public StreamPortItem receive(int maxRecvSize) throws IOException {
177         StreamPortItem item = null;
178         if (serverSoc != null) {
179             byte[] data = new byte[maxRecvSize];
180 
181             // timeout will throw an exception every 1000 secs whilst idle
182             // it is caught and ignored, but as a side effect it loops,
183             // checking 'me'
184             serverSoc.setSoTimeout(1000);
185 
186             Socket newSocket = serverSoc.accept();
187 
188             // copy newSocketIn into in
189             InputStream newSocketIn = newSocket.getInputStream();
190             newSocketIn.read(data, 0, data.length);
191 
192             receiveFromHostAddr = newSocket.getInetAddress();
193             receiveFromHostPort = newSocket.getPort();
194 
195             ByteArrayInputStream in = null;
196             in = new ByteArrayInputStream(data, 0, data.length);
197             item = new StreamPortItem(receiveFromHostAddr.getHostAddress(),
198                     receiveFromHostPort, in);
199 
200             newSocketIn.close();
201             newSocket.close();
202 
203             newSocketIn = null;
204             newSocket = null;
205         } else if (clientSoc != null) {
206             byte[] data = new byte[maxRecvSize];
207 
208             // timeout will throw an exception every 1000 secs whilst idle
209             // it is caught and ignored, but as a side effect it loops,
210             // checking 'me'
211             clientSoc.setSoTimeout(1000);
212 
213             InputStream cin = clientSoc.getInputStream();
214             cin.read(data, 0, data.length);
215 
216             receiveFromHostAddr = clientSoc.getInetAddress();
217             receiveFromHostPort = clientSoc.getPort();
218 
219             ByteArrayInputStream in = null;
220             in = new ByteArrayInputStream(data, 0, data.length);
221             item = new StreamPortItem(receiveFromHostAddr.getHostAddress(),
222                     receiveFromHostPort, in);
223         }
224         return item;
225     }
226 
227     public void send(byte[] packet) throws IOException {
228         if (clientSoc != null) {
229             OutputStream out = clientSoc.getOutputStream();
230             out.write(packet);
231             out.flush();
232         }
233     }
234 
235     public void close() {
236         try {
237             if (clientSoc != null) {
238                 clientSoc.close();
239             }
240         } catch (IOException exc) {
241         }
242 
243         try {
244             if (serverSoc != null) {
245                 serverSoc.close();
246             }
247         } catch (IOException exc) {
248         }
249 
250         serverSoc = null;
251         clientSoc = null;
252     }
253 
254 }