1/* 2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. 3 * Please refer to the LICENSE.txt for licensing details. 4 */ 5package ch.ethz.ssh2.channel; 6 7import java.io.IOException; 8import java.io.InputStream; 9import java.io.OutputStream; 10import java.net.Socket; 11 12/** 13 * A StreamForwarder forwards data between two given streams. 14 * If two StreamForwarder threads are used (one for each direction) 15 * then one can be configured to shutdown the underlying channel/socket 16 * if both threads have finished forwarding (EOF). 17 * 18 * @author Christian Plattner 19 * @version 2.50, 03/15/10 20 */ 21public class StreamForwarder extends Thread 22{ 23 OutputStream os; 24 InputStream is; 25 byte[] buffer = new byte[Channel.CHANNEL_BUFFER_SIZE]; 26 Channel c; 27 StreamForwarder sibling; 28 Socket s; 29 String mode; 30 31 StreamForwarder(Channel c, StreamForwarder sibling, Socket s, InputStream is, OutputStream os, String mode) 32 throws IOException 33 { 34 this.is = is; 35 this.os = os; 36 this.mode = mode; 37 this.c = c; 38 this.sibling = sibling; 39 this.s = s; 40 } 41 42 @Override 43 public void run() 44 { 45 try 46 { 47 while (true) 48 { 49 int len = is.read(buffer); 50 if (len <= 0) 51 break; 52 os.write(buffer, 0, len); 53 os.flush(); 54 } 55 } 56 catch (IOException ignore) 57 { 58 try 59 { 60 c.cm.closeChannel(c, "Closed due to exception in StreamForwarder (" + mode + "): " 61 + ignore.getMessage(), true); 62 } 63 catch (IOException ignored) 64 { 65 } 66 } 67 finally 68 { 69 try 70 { 71 os.close(); 72 } 73 catch (IOException ignored) 74 { 75 } 76 try 77 { 78 is.close(); 79 } 80 catch (IOException ignored) 81 { 82 } 83 84 if (sibling != null) 85 { 86 while (sibling.isAlive()) 87 { 88 try 89 { 90 sibling.join(); 91 } 92 catch (InterruptedException ignored) 93 { 94 } 95 } 96 97 try 98 { 99 c.cm.closeChannel(c, "StreamForwarder (" + mode + ") is cleaning up the connection", true); 100 } 101 catch (IOException ignored) 102 { 103 } 104 105 try 106 { 107 if (s != null) 108 s.close(); 109 } 110 catch (IOException ignored) 111 { 112 } 113 } 114 } 115 } 116}