0
|
1
|
|
2 package com.trilead.ssh2.channel;
|
|
3
|
|
4 import java.io.IOException;
|
|
5 import java.io.InputStream;
|
|
6 import java.io.OutputStream;
|
|
7 import java.net.Socket;
|
|
8
|
|
9 /**
|
|
10 * A StreamForwarder forwards data between two given streams.
|
|
11 * If two StreamForwarder threads are used (one for each direction)
|
|
12 * then one can be configured to shutdown the underlying channel/socket
|
|
13 * if both threads have finished forwarding (EOF).
|
|
14 *
|
|
15 * @author Christian Plattner, plattner@trilead.com
|
|
16 * @version $Id: StreamForwarder.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
|
|
17 */
|
|
18 public class StreamForwarder extends Thread {
|
|
19 final OutputStream os;
|
|
20 final InputStream is;
|
|
21 final byte[] buffer = new byte[Channel.CHANNEL_BUFFER_SIZE];
|
|
22 final Channel c;
|
|
23 final StreamForwarder sibling;
|
|
24 final Socket s;
|
|
25 final String mode;
|
|
26
|
|
27 StreamForwarder(Channel c, StreamForwarder sibling, Socket s, 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
|
|
42 if (len <= 0)
|
|
43 break;
|
|
44
|
|
45 os.write(buffer, 0, len);
|
|
46 os.flush();
|
|
47 }
|
|
48 }
|
|
49 catch (IOException ignore) {
|
|
50 try {
|
|
51 c.cm.closeChannel(c, "Closed due to exception in StreamForwarder (" + mode + "): "
|
|
52 + ignore.getMessage(), true);
|
|
53 }
|
|
54 catch (IOException e) {
|
|
55 }
|
|
56 }
|
|
57 finally {
|
|
58 try {
|
|
59 os.close();
|
|
60 }
|
|
61 catch (IOException e1) {
|
|
62 }
|
|
63
|
|
64 try {
|
|
65 is.close();
|
|
66 }
|
|
67 catch (IOException e2) {
|
|
68 }
|
|
69
|
|
70 if (sibling != null) {
|
|
71 while (sibling.isAlive()) {
|
|
72 try {
|
|
73 sibling.join();
|
|
74 }
|
|
75 catch (InterruptedException e) {
|
|
76 }
|
|
77 }
|
|
78
|
|
79 try {
|
|
80 c.cm.closeChannel(c, "StreamForwarder (" + mode + ") is cleaning up the connection", true);
|
|
81 }
|
|
82 catch (IOException e3) {
|
|
83 }
|
|
84 }
|
|
85
|
|
86 if (s != null) {
|
|
87 try {
|
|
88 s.close();
|
|
89 }
|
|
90 catch (IOException e1) {
|
|
91 }
|
|
92 }
|
|
93 }
|
|
94 }
|
|
95 }
|