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: TcpSocketServer.java,v 1.3 2002/02/04 13:51:40 lizellaman Exp $
025: * $Log: TcpSocketServer.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:15 lizellaman
034: * initial sourceforge release
035: *
036: */
037:
038: package org.datashare;
039:
040: import java.net.ServerSocket;
041: import java.net.Socket;
042: import java.net.BindException;
043: import java.util.Vector;
044:
045: /**
046: * One of these is needed for every TCP port that is to used for communicating with Clients.
047: * This class is given a port number, and when Clients establish a connection to that port,
048: * a TCP socket handler is created to communicate over that socket with the Client.
049: * The design of this class is such that if this socket closes (through some type of error),
050: * the socket connections to other clients that have already been established will remain
051: * functional, but no new clients can be added to the connection/channel.
052: * @date March 01, 2001
053: */
054: public class TcpSocketServer extends Thread implements
055: SocketServerInterface {
056: private DataReceiverInterface dri = null; // how we communicate when connections come and go
057: private int port; // our local port number
058: private int priority; // what priority to give the sockets
059: private ServerSocket server = null;
060: public boolean running = true; // true as long as it is desired to handle connections
061: private boolean available = false;
062: private String keyValue; // key value for this TCP server socket, must be unique
063:
064: /**
065: * Constructor, creates a server socket on the specified port
066: */
067: public TcpSocketServer(DataReceiverInterface dri, int port,
068: int priority) {
069: boolean stillTrying = true;
070: int count = 0;
071: SessionUtilities.getLoggingInterface().debugMsg(
072: SessionUtilities.getLoggingInterface().DEBUG,
073: SessionUtilities.getLoggingInterface().NETWORK,
074: "TcpSocketServer created for port " + port);
075: this .dri = dri;
076: this .port = port;
077: this .priority = priority;
078: keyValue = "TCP:" + port;
079: this .setName("DataShare.SocketServer." + keyValue);
080: while (stillTrying && (count++) < 50) {
081: try {
082: server = new ServerSocket(this .port);
083: stillTrying = false;
084: } catch (BindException be) {
085: SessionUtilities
086: .getLoggingInterface()
087: .debugMsg(
088: SessionUtilities.getLoggingInterface().WARNING,
089: SessionUtilities.getLoggingInterface().NETWORK,
090: "TCP Socket appears to be in use, try next one...");
091: // try next port
092: this .port = dri.getNextPort();
093: } catch (Exception e) {
094: e.printStackTrace();
095: dri.lostServerSocket(keyValue);
096: running = false;
097: stillTrying = false;
098: }
099: }
100: }
101:
102: /**
103: * return our local port
104: */
105: public int getLocalPort() {
106: return port;
107: }
108:
109: /**
110: * returns true if ready to receive connections
111: */
112: public boolean getReady() {
113: return available;
114: }
115:
116: /**
117: * returns the unique key value string for this server socket instance
118: */
119: public String getKeyValue() {
120: return keyValue;
121: }
122:
123: /**
124: * this method will stop this class from creating sockets and will kill this thread
125: */
126: public void killThread() {
127: running = false;
128: }
129:
130: public void run() {
131: SessionUtilities.getLoggingInterface()
132: .debugMsg(
133: SessionUtilities.getLoggingInterface().DEBUG,
134: SessionUtilities.getLoggingInterface().NETWORK,
135: "Setting " + this .keyValue + " to priority "
136: + priority);
137: setPriority(priority);
138: while (running) {
139: try {
140: SessionUtilities.getLoggingInterface().debugMsg(
141: SessionUtilities.getLoggingInterface().DEBUG,
142: SessionUtilities.getLoggingInterface().NETWORK,
143: "waiting for TCP connection on " + port);
144: available = true;
145: Socket socket = server.accept();
146: SessionUtilities.getLoggingInterface().debugMsg(
147: SessionUtilities.getLoggingInterface().DEBUG,
148: SessionUtilities.getLoggingInterface().CLIENT,
149: "Client connecting to TCP port " + port);
150: // create a thread to handle traffic for new connection, then start it
151: if (socket != null) {
152: TcpSocket newSocket = new TcpSocket(socket, dri,
153: priority);
154: Thread thread = new Thread(newSocket, "DataShare."
155: + newSocket.getKeyValue());
156: thread.start();
157: dri.newConnection(newSocket); // now our new socket is known to the DataReceiverAdapter
158: yield();
159: }
160: } catch (Exception e) {
161: try {
162: server.close();
163: } catch (Exception e2) {
164: e2.printStackTrace();
165: } finally {
166: if (running) // true if we called close, and we know it will generate an exception
167: {
168: dri.lostServerSocket(keyValue);
169: e.printStackTrace();
170: running = false;
171: }
172: }
173: }
174: }
175: SessionUtilities.getLoggingInterface().debugMsg(
176: SessionUtilities.getLoggingInterface().DEBUG,
177: SessionUtilities.getLoggingInterface().NETWORK,
178: "Thread " + getName() + " has stopped");
179: }
180:
181: /**
182: * close the socket, stop any thread, and notify the server
183: */
184: public void close() {
185: SessionUtilities.getLoggingInterface().debugMsg(
186: SessionUtilities.getLoggingInterface().DEBUG,
187: SessionUtilities.getLoggingInterface().NETWORK,
188: "removing socket server " + keyValue);
189: try {
190: running = false;
191: server.close();
192: dri.lostServerSocket(keyValue);
193: } catch (Exception e) {
194: e.printStackTrace();
195: }
196: }
197:
198: }
|