001: /* ----- BEGIN LICENSE BLOCK -----
002: * Version: MPL 1.1
003: *
004: * The contents of this file are subject to the Mozilla Public License Version
005: * 1.1 (the "License"); you may not use this file except in compliance with
006: * the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS" basis,
010: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011: * for the specific language governing rights and limitations under the
012: * License.
013: *
014: * The Original Code is the DataShare server.
015: *
016: * The Initial Developer of the Original Code is
017: * Ball Aerospace & Technologies Corp, Fairborn, Ohio
018: * Portions created by the Initial Developer are Copyright (C) 2001
019: * the Initial Developer. All Rights Reserved.
020: *
021: * Contributor(s): Charles Wood <cwood@ball.com>
022: *
023: * ----- END LICENSE BLOCK ----- */
024: /* RCS $Id: UdpSocketServer.java,v 1.3 2002/02/04 13:51:40 lizellaman Exp $
025: * $Log: UdpSocketServer.java,v $
026: * Revision 1.3 2002/02/04 13:51:40 lizellaman
027: * Remove all references to past product names (or)
028: * Add PublicAPI for creating Rendezvous Sessions
029: *
030: * Revision 1.2 2002/01/29 20:50:17 lizellaman
031: * Added LoggingInterface, modified the PropertiesInterface implementation
032: *
033: * Revision 1.1.1.1 2001/10/23 13:37:16 lizellaman
034: * initial sourceforge release
035: *
036: */
037:
038: package org.datashare;
039:
040: import java.net.DatagramPacket;
041: import java.net.DatagramSocket;
042: import java.net.InetAddress;
043: import java.util.Hashtable;
044: import java.util.Enumeration;
045: import java.io.IOException;
046:
047: /**
048: * We need one of these for each UDP connection that clients might use
049: */
050: public class UdpSocketServer extends Thread implements
051: SocketServerInterface {
052: DataReceiverInterface dri = null;
053: DatagramSocket socket = null;
054: DatagramPacket sndPacket = null;
055: DatagramPacket rcvPacket = null;
056: boolean running = true;
057: Hashtable connections = new Hashtable();
058: InetAddress myIpAddress;
059: String keyValue;
060: boolean active = false;
061: int priority;
062: int port;
063:
064: public UdpSocketServer(InetAddress myIpAddress,
065: DataReceiverInterface dri, int port, int priority) {
066: SessionUtilities.getLoggingInterface().debugMsg(
067: SessionUtilities.getLoggingInterface().DEBUG,
068: SessionUtilities.getLoggingInterface().NETWORK,
069: "UdpSocketServer created for port " + port);
070: this .dri = dri;
071: this .port = port;
072: this .priority = priority;
073: this .myIpAddress = myIpAddress;
074: keyValue = "UDP:" + port;
075: this .setName("DataShare.SocketServer." + keyValue);
076: createSocket(true);
077: if (SessionUtilities.getVerbose()) {
078: try {
079: SessionUtilities.getLoggingInterface().debugMsg(
080: SessionUtilities.getLoggingInterface().DEBUG,
081: SessionUtilities.getLoggingInterface().NETWORK,
082: "UDP socket max receive size is "
083: + socket.getReceiveBufferSize() + "\n"
084: + "UDP socket max send size is "
085: + socket.getSendBufferSize());
086: } catch (Exception e) {
087: }
088: }
089: }
090:
091: /**
092: * actually creates the socket
093: */
094: private void createSocket(boolean firsttime) {
095: try {
096: SessionUtilities.getLoggingInterface().debugMsg(
097: SessionUtilities.getLoggingInterface().DEBUG,
098: SessionUtilities.getLoggingInterface().NETWORK,
099: (firsttime ? "Creating" : "Re-creating")
100: + " UdpSocketServer socket for port "
101: + port);
102: socket = new DatagramSocket(port);
103: socket.setReceiveBufferSize(99999);
104: socket.setSendBufferSize(99999);
105: } catch (Exception e) {
106: e.printStackTrace();
107: socket = null;
108: }
109: }
110:
111: /**
112: * returns true if ready to receive connections
113: */
114: public boolean getReady() {
115: return active;
116: }
117:
118: /**
119: * return our local port
120: */
121: public int getLocalPort() {
122: return port;
123: }
124:
125: /**
126: * returns our keyValue
127: */
128: public String getKeyValue() {
129: return this .keyValue;
130: }
131:
132: /**
133: * this method is where we receive data and establish new 'connections'
134: */
135: public void run() {
136: String udpKey = "";
137: SessionUtilities.getLoggingInterface()
138: .debugMsg(
139: SessionUtilities.getLoggingInterface().DEBUG,
140: SessionUtilities.getLoggingInterface().NETWORK,
141: "Setting " + this .keyValue + " to priority "
142: + priority);
143: setPriority(priority);
144: while (running) {
145: try {
146: DatagramPacket packet = new DatagramPacket(
147: new byte[10001], 10001);
148: active = true;
149: udpKey = "";
150: socket.receive(packet); // blocks until client connects
151: // create unique (to this class) key for 'connection'
152: udpKey = packet.getAddress().getHostAddress() + ":"
153: + packet.getPort();
154: if (connections.containsKey(udpKey)) {
155: // forward to the udpSocket for this connection
156: UdpSocket handler = (UdpSocket) connections
157: .get(udpKey);
158: handler.newData(packet);
159: } else {
160: // new client!
161: UdpSocket newHandler = new UdpSocket(this , socket,
162: packet, dri, myIpAddress);
163: connections.put(udpKey, newHandler);
164: dri.newConnection(newHandler); // now our new socket is known to the DataReceiverAdapter
165: newHandler.newData(packet); // now send this data to handler
166: }
167: Thread.currentThread().yield();
168: } // end of the try
169: catch (IOException ioe) {
170: if (running) // ignore any errors if we have decided to shutdown
171: {
172: boolean found = false;
173: SessionUtilities
174: .getLoggingInterface()
175: .debugMsg(
176: SessionUtilities
177: .getLoggingInterface().ERROR,
178: SessionUtilities
179: .getLoggingInterface().NETWORK,
180: "Problems ("
181: + ioe
182: + ") receiving data over UDPSocket "
183: + udpKey);
184: if (!udpKey.equals("")) // try to shutdown just the connection that had problems...
185: {
186: try {
187: socket.close();
188: } catch (Exception ee) {
189: }
190:
191: // try to reconnect...
192: createSocket(false);
193:
194: // go ahead and shut down the client and make them reconnect too
195: if (connections.containsKey(udpKey)) {
196: found = true;
197: UdpSocket handler = (UdpSocket) connections
198: .get(udpKey);
199: handler.close();
200: }
201: }
202: if (!found) {
203: SessionUtilities
204: .getLoggingInterface()
205: .debugMsg(
206: SessionUtilities
207: .getLoggingInterface().ERROR,
208: SessionUtilities
209: .getLoggingInterface().NETWORK,
210: "UDPSocketServer Problem ("
211: + ioe
212: + ") that was not traced to a known socket:");
213: //ioe.printStackTrace();
214: //close();
215: }
216: }
217: } catch (Exception e) {
218: e.printStackTrace();
219: // now we need to notify everybody that this connection is dead!!
220: close();
221: }
222: } // end of the while
223: SessionUtilities.getLoggingInterface().debugMsg(
224: SessionUtilities.getLoggingInterface().DEBUG,
225: SessionUtilities.getLoggingInterface().NETWORK,
226: "Thread " + getName() + " has stopped (scheduled)");
227: }
228:
229: /**
230: * close the socket, stop any thread, and notify the server
231: */
232: public void close()
233: {
234: SessionUtilities.getLoggingInterface().debugMsg(SessionUtilities.getLoggingInterface().DEBUG,
235: SessionUtilities.getLoggingInterface().NETWORK,
236: "removing socket server " + keyValue);
237: running = false;
238: try{
239: try{
240: socket.close();
241: }
242: catch(Exception ee){}
243:
244: dri.lostServerSocket(keyValue);
245:
246: // close all the spawned sockets
247: for(Enumeration enum = connections.elements(); enum.hasMoreElements();)
248: {
249: UdpSocket udps = (UdpSocket)enum.nextElement();
250: udps.close();
251: }
252: }
253: catch(Exception e)
254: {
255: e.printStackTrace();
256: }
257: }
258:
259: /**
260: * called by socket when it closes itself
261: */
262: public void closeSocket(UdpSocket socket) {
263: String udpKey = socket.getRemoteIP().getHostAddress() + ":"
264: + socket.getLocalPort();
265: SessionUtilities.getLoggingInterface().debugMsg(
266: SessionUtilities.getLoggingInterface().DEBUG,
267: SessionUtilities.getLoggingInterface().NETWORK,
268: "closeSocket called for " + socket.getKeyValue());
269: connections.remove(udpKey);
270: }
271:
272: }
|