public PipedSocketStream(Socket s1,
Socket s2) {
try {
dis =
new DataInputStream(s1.getInputStream());
dos =
new DataOutputStream(s2.getOutputStream());
}
catch(IOException ioe)
{
ioe.printStackTrace();
System.exit(1);
}
} // End PipedSocketStream() constructor
public void run() {
// Read and write from
piped sockets
while(true) {
try {
if (!this.readAndWrite())
return;
}
catch (IOException
e) {
return;
}
}
} // End run() method
private synchronized boolean readAndWrite()
throws IOException
{
if ((ch = dis.read())
< 0)
return false;
dos.write(ch);
dos.flush();
return true;
} // End readAndWrite() method
} // End Class PipedSocketStream
Listing 2: jtunnel.java.
import java.net.*;
import java.io.*;
import java.lang.Thread;
public class JTunnel {
public Socket cSocket;
public Socket sSocket;
private Thread clientServerPipe;
private Thread serverClientPipe;
public JTunnel(Socket in_cSocket,
Socket in_sSocket) {
cSocket = in_cSocket;
sSocket = in_sSocket;
} // End JTunnel constructor
// Create and activate PipedSocketStreams
public void JTopen() {
clientServerPipe =
new Thread(new
PipedSocketStream(cSocket,
sSocket));
serverClientPipe =
new Thread(new
PipedSocketStream(sSocket,
cSocket));
System.out.println("Starting
socket pipes");
clientServerPipe.start();
serverClientPipe.start();
} // End openJT() method
public boolean isActive() {
if (clientServerPipe.isAlive()
&&
serverClientPipe.isAlive())
return true;
return false;
} // End isActive() method
public void JTclose() {
if (clientServerPipe.isAlive())
clientServerPipe.stop();
if (serverClientPipe.isAlive())
serverClientPipe.stop();
try {
if (cSocket
!= null)
cSocket.close();
if (sSocket
!= null)
sSocket.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
} // End closeJT() method
public void finalize()
{
JTclose();
} // End finalize() method
} // End class JTunnel
Listing 3: jtserver.java.
import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.*;
class JTServer implements Runnable{
public int clientPort = 0;
private int remoteHostPort = 0;
private String remoteHostAddr = null;
private Vector jTunnels = new Vector();
public Vector jtPending = new Vector();
public int activeConnections = 0;
public boolean jtChanged = true;
public static void main(String[] args)
{
int in_clientPort = 0;
int in_remoteHostPort
= 0;
String in_remoteHostAddr
= null;
DataInputStream dis =
new DataInputStream(System.in);
try {
System.out.println("Caller
port: ");
in_clientPort
=
Integer.parseInt(dis.readLine());
System.out.println("Remote
Host Port: ");
in_remoteHostPort
=
Integer.parseInt(dis.readLine());
System.out.println("Remote
Host Address:");
in_remoteHostAddr
= dis.readLine();
}
catch (IOException ioe)
{
ioe.printStackTrace();
System.exit(1);
}
// Create and start JTServer
thread
Thread jts = new Thread
(
new JTServer(in_clientPort,
in_remoteHostPort, in_remoteHostAddr));
jts.run();
} // End main()
public JTServer(int in_clientPort,
int in_remoteHostPort,
String in_remoteHostAddr) {
clientPort = in_clientPort;
remoteHostPort = in_remoteHostPort;
remoteHostAddr = in_remoteHostAddr;
}
public synchronized void run() {
Thread jtListener =
new Thread(new
JTListener(this));
jtListener.start();
jtChanged = false;
while (true) {
try {
this.wait(100);
}
catch (InterruptedException
ie) {
ie.printStackTrace();
}
// Clear JTunnels
with dead threads
processQueuedConnections();
cleanJTunnels();
if (jtChanged)
{
System.out.println("No. of JTunnels = " +
activeConnections);
jtChanged = false;
}
} // End while loop
} // End run() method
void processQueuedConnections() {
Vector newJTunnels = new
Vector();
if (jtPending.size() ==
0)
return;
synchronized (jtPending)
{
for (int i
= 0;
i < jtPending.size(); i++) {
newJTunnels.addElement((Socket)
(jtPending.elementAt(i)));
}
// Clear the
JTunnels Pending queue
jtPending.removeAllElements();
}
for (int i = 0; i <
newJTunnels.size(); i++) {
Socket clientSocket
=
(Socket)(newJTunnels.elementAt(i));
// connect
to remoteHost
Socket remoteHostSocket
= connectToRemoteHost();
if (remoteHostSocket
== null)
continue;
// Create New
JTunnel; add it to JTunnels
JTunnel jTunnel
= null;
try {
jTunnel = new JTunnel(clientSocket,
remoteHostSocket);
jTunnel.JTopen();
}
catch(Exception
e) {
e.printStackTrace();
System.exit(1);
}
jTunnels.addElement(jTunnel);
activeConnections++;
jtChanged
= true;
} // End for loop
} // End processQueuedConnections()
method
// Try to connect to the remote host
public Socket connectToRemoteHost()
{
Socket sock;
try {
sock = new
Socket(remoteHostAddr,
remoteHostPort);
}
catch(IOException ioe)
{
ioe.printStackTrace();
return null;
}
return sock;
} // End method connectToRemtoeHost()
// Close JTunnels associated with dead
threads
void cleanJTunnels() {
for (int i = 0; i <
jTunnels.size(); i++) {
JTunnel jTunnel
=
(JTunnel)(jTunnels.elementAt(i));
if (!(jTunnel.isActive()))
{
jTunnel.JTclose();
jTunnels.removeElementAt(i);
jtChanged = true;
activeConnections--;
}
}
} // End checkJTunnels() method
} //End Class JTServer
Listing 4: JTListener.java.
import java.io.*;
import java.net.*;
import java.lang.Thread;
class JTListener implements Runnable {
private JTServer jts;
private ServerSocket jtServerSocket
= null;
public JTListener(JTServer in_jts)
{
jts = in_jts;
try {
jtServerSocket
=
new ServerSocket(jts.clientPort);
System.out.println("Server
started on port "
+ jts.clientPort);
}
catch(IOException ioe)
{
ioe.printStackTrace();
System.exit(2);
}
} // end method createJTServerSocket
public void run() {
while (true) {
System.out.println("Accepting
connections");
try {
Thread.sleep(100);
}
catch (InterruptedException
ie) {
break;
}
// Accept internet
connection requests
Socket clientSocket;
if ((clientSocket
= acceptConnection())
== null) {
System.out.println("Got null socket");
System.exit(1);
}
System.out.println("Got
request, " +
"clientSocket
= " + clientSocket);
synchronized(jts.jtPending)
{
jts.jtPending.addElement(clientSocket);
}
synchronized(jts)
{
jts.notify();
}
} // End while loop
} // End run() method
// accept client connections
private Socket acceptConnection()
{
Socket sock = null;
try {
sock = jtServerSocket.accept();
System.out.println("Connection
from: " +
sock.getInetAddress().toString());
}
catch(Exception e) {
e.printStackTrace();
System.exit(4);
}
return sock;
} // End method acceptConnection()
} // End Class JTListener