/***Chuck Hall 1999
*SFSU
*
* The relay class copies data
* from the input stream to the output stream.
*
* Relay extends thread, allowing multiple instances
* of relay to coexist.
* 
* Interfaces:
*	Setup(ProxSocket, DataInputStream, DataOutputStream)
*		Passes the streams and parent class to Relay
*		The parent needs to be a thread.
*		This is just so that we can resume() the 
*		Parent process.
*
*
*	Run()
*		This is the main method.
*		It will copy from the one stream to the other 
*		As long as both stream remain open.
*		Once one of the streams closes, it will shutdown 
*		And attempt to shutdown its peer.*
*
*        Copyright 1999, Charles Hall
*
*This program is free software; you can redistribute it and/or *modify it under the terms of the GNU General Public License as *published by the Free Software Foundation; either version 2 of *the License.
*
*This program is distributed in the hope that it will be useful, *but WITHOUT ANY WARRANTY; without even the implied warranty of *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public *License along with this program; if not, write to the Free *Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, *MA 02111-1307  USA
*/


import java.io.*;


public class Relay extends Thread {

   private BufferedInputStream  s1;

   private BufferedOutputStream s2; 

   private Thread Parent ;

   private int iTerminate = 0 ;

   private byte[] InBuffer1024 = new byte[1024] ;

   private byte[] OutBuffer = new byte[16384] ;

   private int iHaveRead, iToWrite, iWritten ;





   public void Setup(Thread Parent,

                     DataInputStream sNew1, 

                     DataOutputStream sNew2) {

      this.Parent = Parent ;

      this.s1 = new BufferedInputStream(sNew1);

      this.s2 = new BufferedOutputStream(sNew2);

      

   }



   public void run() {

      

      // read from input s1

      iHaveRead = -1 ;



      try {

         iHaveRead = s1.read(InBuffer1024, 0, 1024) ;

      } catch(IOException e) {

		System.out.println("Relay Failure\n");
		e.printStackTrace();
        iHaveRead = -1 ;

      }  



      while(iHaveRead != -1) {

         // call process line

         iToWrite = ProcData(iHaveRead) ;



         // write to s2

         

         try {

            s2.write(OutBuffer, 0, iToWrite) ;

            s2.flush() ;

         } catch(IOException e) {

           iHaveRead = -1 ;

           break ;

         }



         // be kind to everyone else

         yield() ;



         try {

            iHaveRead = s1.read(InBuffer1024, 0, 1024) ;

         } catch(IOException e) {

           iHaveRead = -1 ;

           break ;

         }

      }//while





	try{
	 int flag =0;
	 while(flag!=-1){
		flag=s1.read(InBuffer1024,0,1024);
	 }//while
	}catch(IOException e){e.printStackTrace();}
	 Parent.resume();
   }





   // mod. the input Buffer, and write results to the output Buffer

   // return the length of the output Buffer



   private int ProcData(int iReadd) {



      // simply copy input to output here

      System.arraycopy(InBuffer1024, 0, OutBuffer, 0, iReadd) ;

 

      return(iReadd) ;

   }

}

    Source: geocities.com/siliconvalley/way/5970

               ( geocities.com/siliconvalley/way)                   ( geocities.com/siliconvalley)