src.com.ibm.as400.access.PSController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400-jdk9 Show documentation
Show all versions of jt400-jdk9 Show documentation
The Open Source version of the IBM Toolbox for Java
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: PSController.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2000 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Vector;
// Represents a connection to a client of the proxy server.
class PSController extends StoppableThread
{
// Private data.
private static long nextConnectionId_ = 1000;
private static Object nextConnectionIdLock_ = new Object();
private boolean closed_ = false;
//private PSConfig config_;
private Socket connectedSocket_;
private long connectionId_ = -1;
private PxDSFactory factory_;
private InputStream input_;
private boolean ownSocket_ = false;
private OutputStream output_;
private boolean running_ = false;
private PSServerSocketContainerAdapter serverSocket_;
//private Vector threadGroup_;
// Constructs a PSController object.
// @param threadGroup The thread group.
// @param proxyServer The proxy server.
// @param load The load.
// @param loadBalancer The load balancer.
// @param config The configuration.
// @param serverSocket The server socket container.
public PSController(Vector threadGroup, ProxyServer proxyServer, PSLoad load, PSLoadBalancer loadBalancer, PSConfig config, PSServerSocketContainerAdapter serverSocket)
{
super("PSController-" + serverSocket);
//threadGroup_ = threadGroup;
//config_ = config;
serverSocket_ = serverSocket;
factory_ = new PxDSFactory();
factory_.register(new PxBooleanParm());
factory_.register(new PxIntParm());
factory_.register(new PxStringParm());
factory_.register(new PxSerializedObjectParm(null));
factory_.register(new PxConnectReqSV(threadGroup, this, load, loadBalancer));
factory_.register(new PxConfigReqSV(config, this));
factory_.register(new PxEndReqSV(proxyServer, this));
factory_.register(new PxLoadReqSV(load));
if (Trace.isTraceOn()) Trace.log(Trace.PROXY, "Px server controller " + this + " opened.");
}
public void closeServerSocket()
{
if (Trace.isTraceOn()) Trace.log(Trace.PROXY, "Px server controller " + this + " closed.");
closeSocket();
try
{
serverSocket_.close();
}
catch (IOException e)
{
Trace.log(Trace.ERROR, e.getMessage(), e);
}
closed_ = true;
}
public void closeSocket()
{
if (ownSocket_)
{
try
{
if (connectedSocket_ != null) connectedSocket_.close();
}
catch (IOException e)
{
Trace.log(Trace.ERROR, "Exception closing proxy socket:", e);
}
ownSocket_ = false;
}
}
protected void finalize() throws Throwable
{
if (closed_ == false) closeServerSocket();
super.finalize();
}
// Returns the current requesting client's address.
// @return The current requesting client's address.
public InetAddress getClientAddress()
{
return connectedSocket_.getInetAddress();
}
// Returns the current requesting client's socket.
// @return The current requesting client's socket.
public Socket getConnectedSocket()
{
// Give up ownership of the socket. A connection owns it now.
ownSocket_ = false;
return connectedSocket_;
}
// Returns the current requesting client's unique connection id.
// @return The current requesting client's unique connection id.
public long getConnectionId()
{
return connectionId_;
}
// Returns the input stream used for receiving requests from the current client.
// @return The input stream used for receiving requests from the current client.
public InputStream getInputStream()
{
return input_;
}
// Returns the output stream used for sending replies to the current client.
// @return The output stream used for sending replies to the current client.
public OutputStream getOutputStream()
{
return output_;
}
// Runs the controller.
public void run()
{
running_ = true;
// Loop forever, handling each connection that comes in.
while (canContinue())
{
// If anything goes wrong here, stop the controller.
try
{
connectedSocket_ = serverSocket_.accept();
// Test note: We see the phrase "Address in use: bind" on occasion when calling this method. My best guess is that the JDK is printing it!
}
catch(Exception e)
{
Verbose.println(e);
Trace.log(Trace.ERROR, "Exception accepting proxy socket:", e);
break;
}
// From here on out, if anything goes wrong, we just loop and try again!
try
{
input_ = new BufferedInputStream(connectedSocket_.getInputStream());
output_ = new BufferedOutputStream(connectedSocket_.getOutputStream());
// For now, this class "owns" the socket... at least until a connection gets it for its own use.
ownSocket_ = true;
synchronized (nextConnectionIdLock_)
{
connectionId_ = ++nextConnectionId_;
}
// Get the next request.
PxReqSV request = (PxReqSV)factory_.getNextDS(input_);
if (Trace.isTraceProxyOn()) request.dump(Trace.getPrintWriter());
// Process the request and return the reply, if any.
PxRepSV reply = (PxRepSV)request.process();
if (reply != null)
{
reply.setCorrelationId(request.getCorrelationId());
synchronized (output_)
{
if (Trace.isTraceProxyOn()) reply.dump(Trace.getPrintWriter());
reply.writeTo(output_);
output_.flush();
}
}
}
catch (Exception e)
{
Verbose.println(e);
Trace.log(Trace.ERROR, "Exception processing proxy request:", e);
}
finally
{
closeSocket();
}
}
running_ = false;
}
// Stops the thread safely.
public void stopSafely()
{
super.stopSafely();
// Close the sockets, etc.
closeServerSocket();
// Wait for controller loop to finish. This verifies that the socket was finally closed. (On some platforms (e.g. Windows) it seems like the close does not take full effect until a few seconds after close() is called.
try
{
while (running_) Thread.sleep(500);
}
catch(InterruptedException e)
{
// Ignore.
}
Verbose.println(ResourceBundleLoader.getText("PROXY_SERVER_ENDED", serverSocket_));
}
public String toString()
{
return serverSocket_.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy