import java.net.Socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
class Connection implements Runnable, AgentMonitor
{
private String destHost = null;
private int destPort = -1;
private Agent fromSrcToDest = null;
private Agent fromDestToSrc = null;
private Socket srcSocket = null;
private Socket destSocket = null;
private InputStream srcIn = null;
private OutputStream srcOut = null;
private InputStream destIn = null;
private OutputStream destOut = null;
private ConnectionMonitor cm = null;
private boolean connectionClosed = false;
private boolean echo = false;
public Connection
(
Socket s,
ConnectionMonitor cm,
String destHost,
int destPort,
boolean echo
)
{
srcSocket = s;
this.cm = cm;
this.destHost = destHost;
this.destPort = destPort;
this.echo = echo;
cm.attemptingConnection(this);
try
{
// Establish read/write for the socket
srcIn = s.getInputStream();
srcOut = s.getOutputStream();
// Start ourself, so there's no delay in getting back
// to the server to listen for new connections
Thread t = new Thread(this);
t.start();
}
catch(IOException e)
{
cm.connectionError(this, "" + e);
}
}
public void run()
{
if(!connectToDest())
{
closeSrc();
}
else
{
// Ok, we're all ready ... since we've gotten this far,
// add ourselves into the connection list
cm.addConnection(this);
// Create our two agents
fromSrcToDest = new Agent(srcIn, destOut, this, "Client => Server", echo);
fromDestToSrc = new Agent(destIn, srcOut, this, "Server => Client", echo);
// No need for our thread to continue, we'll be notified if
// either of our agents dies
}
}
public synchronized void agentHasDied(Agent a)
{
// When one agent dies, so will the other ... if the
// connection is already closed then we have already been
// visited by the first agent ... just return
if(connectionClosed) return;
closeSrc();
closeDest();
cm.removeConnection(this);
connectionClosed = true;
}
private boolean connectToDest()
{
// Ok, we've got the host name and port to which we wish to
// connect, try to establish a connection
try
{
destSocket = new Socket(destHost, destPort);
destIn = destSocket.getInputStream();
destOut = destSocket.getOutputStream();
}
catch(Exception e)
{
cm.connectionError(this, "connect error: "
+ destHost + "/" + destPort + " " + e);
return(false);
}
return(true);
}
private void closeSrc()
{
try
{
srcIn.close(); srcOut.close(); srcSocket.close();
}
catch(Exception e) {}
}
private void closeDest()
{
try
{
destIn.close(); destOut.close(); destSocket.close();
}
catch(Exception e) {}
}
public String getSrcHost()
{
return(srcSocket.getInetAddress().toString());
}
public String getDestHost()
{
return(destSocket.getInetAddress().toString());
}
public int getDestPort()
{
return(destPort);
}
}