01: package ch.ethz.ssh2.channel;
02:
03: import java.io.IOException;
04: import java.io.InputStream;
05: import java.io.OutputStream;
06: import java.net.Socket;
07:
08: /**
09: * A StreamForwarder forwards data between two given streams.
10: * If two StreamForwarder threads are used (one for each direction)
11: * then one can be configured to shutdown the underlying channel/socket
12: * if both threads have finished forwarding (EOF).
13: *
14: * @author Christian Plattner, plattner@inf.ethz.ch
15: * @version $Id: StreamForwarder.java,v 1.2 2006/02/13 21:19:25 cplattne Exp $
16: */
17: public class StreamForwarder extends Thread {
18: OutputStream os;
19: InputStream is;
20: byte[] buffer = new byte[Channel.CHANNEL_BUFFER_SIZE];
21: Channel c;
22: StreamForwarder sibling;
23: Socket s;
24: String mode;
25:
26: StreamForwarder(Channel c, StreamForwarder sibling, Socket s,
27: InputStream is, OutputStream os, String mode)
28: throws IOException {
29: this .is = is;
30: this .os = os;
31: this .mode = mode;
32: this .c = c;
33: this .sibling = sibling;
34: this .s = s;
35: }
36:
37: public void run() {
38: try {
39: while (true) {
40: int len = is.read(buffer);
41: if (len <= 0)
42: break;
43: os.write(buffer, 0, len);
44: os.flush();
45: }
46: } catch (IOException ignore) {
47: try {
48: c.cm.closeChannel(c,
49: "Closed due to exception in StreamForwarder ("
50: + mode + "): " + ignore.getMessage(),
51: true);
52: } catch (IOException e) {
53: }
54: } finally {
55: try {
56: os.close();
57: } catch (IOException e1) {
58: }
59: try {
60: is.close();
61: } catch (IOException e2) {
62: }
63:
64: if (sibling != null) {
65: while (sibling.isAlive()) {
66: try {
67: sibling.join();
68: } catch (InterruptedException e) {
69: }
70: }
71:
72: try {
73: c.cm.closeChannel(c, "StreamForwarder (" + mode
74: + ") is cleaning up the connection", true);
75: } catch (IOException e3) {
76: }
77:
78: try {
79: if (s != null)
80: s.close();
81: } catch (IOException e1) {
82: }
83: }
84: }
85: }
86: }
|