KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > spy > TcpipSpy


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdi.internal.spy;
12
13
14 import java.io.BufferedInputStream JavaDoc;
15 import java.io.BufferedOutputStream JavaDoc;
16 import java.io.DataInputStream JavaDoc;
17 import java.io.DataOutputStream JavaDoc;
18 import java.io.EOFException JavaDoc;
19 import java.io.File JavaDoc;
20 import java.io.FileNotFoundException JavaDoc;
21 import java.io.FileOutputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.net.InetAddress JavaDoc;
26 import java.net.ServerSocket JavaDoc;
27 import java.net.Socket JavaDoc;
28 import java.net.SocketException JavaDoc;
29 import com.ibm.icu.text.MessageFormat;
30 import java.util.HashMap JavaDoc;
31 import java.util.Map JavaDoc;
32
33 /**
34  * This class can be used to spy all JDWP packets. It should be configured 'in between' the debugger
35  * application and the VM (or J9 debug proxy).
36  * Its parameters are:
37  * 1) The port number to which the debugger application connects;
38  * 2) The name of the host on which the VM or proxy waits for a JDWP connection;
39  * 3) The port number on which the VM or proxy waits for a JDWP connection;
40  * 4) The file where the trace is written to.
41  *
42  * Note that if this program is used for tracing JDWP activity of Leapfrog, the
43  * 'debug remote program' option must be used, and the J9 proxy must first be started up by hand
44  * on the port to which Leapfrog will connect.
45  * The J9 proxy that is started up by Leapfrog is not used and will return immediately.
46  */

47 public class TcpipSpy extends Thread JavaDoc {
48
49     private static final byte[] handshakeBytes= "JDWP-Handshake".getBytes(); //$NON-NLS-1$
50
private boolean fVMtoDebugger;
51     private DataInputStream JavaDoc fDataIn;
52     private DataOutputStream JavaDoc fDataOut;
53
54     private static VerbosePacketStream out= new VerbosePacketStream(System.out);
55     private static Map JavaDoc fPackets= new HashMap JavaDoc();
56
57     private static int fFieldIDSize;
58     private static int fMethodIDSize;
59     private static int fObjectIDSize;
60     private static int fReferenceTypeIDSize;
61     private static int fFrameIDSize;
62     private static boolean fHasSizes;
63
64     public TcpipSpy(boolean VMtoDebugger, InputStream JavaDoc in, OutputStream JavaDoc out) {
65         fVMtoDebugger= VMtoDebugger;
66         fDataIn= new DataInputStream JavaDoc(new BufferedInputStream JavaDoc(in));
67         fDataOut= new DataOutputStream JavaDoc(new BufferedOutputStream JavaDoc(out));
68         fHasSizes= false;
69     }
70
71     public static void main(String JavaDoc[] args) {
72         int inPort= 0;
73         String JavaDoc serverHost= null;
74         int outPort= 0;
75         String JavaDoc outputFile= null;
76         try {
77             inPort= Integer.parseInt(args[0]);
78             serverHost= args[1];
79             outPort= Integer.parseInt(args[2]);
80             if (args.length > 3) {
81                 outputFile= args[3];
82             }
83         } catch (Exception JavaDoc e) {
84             out.println("usage: TcpipSpy <client port> <server host> <server port> [<output file>]"); //$NON-NLS-1$
85
System.exit(-1);
86         }
87
88         if (outputFile != null) {
89             File JavaDoc file= new File JavaDoc(outputFile);
90             out.println(MessageFormat.format("Writing output to {0}", new String JavaDoc[] {file.getAbsolutePath()})); //$NON-NLS-1$
91
try {
92                 out= new VerbosePacketStream(new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(file)));
93             } catch (FileNotFoundException JavaDoc e) {
94                 out.println(MessageFormat.format("Could not open {0}. Using stdout instead", new String JavaDoc[] {file.getAbsolutePath()})); //$NON-NLS-1$
95
}
96         }
97         out.println();
98         try {
99             ServerSocket JavaDoc serverSock= new ServerSocket JavaDoc(inPort);
100             Socket JavaDoc inSock= serverSock.accept();
101             Socket JavaDoc outSock= new Socket JavaDoc(InetAddress.getByName(serverHost), outPort);
102             new TcpipSpy(false, inSock.getInputStream(), outSock.getOutputStream()).start();
103             new TcpipSpy(true, outSock.getInputStream(), inSock.getOutputStream()).start();
104         } catch (Exception JavaDoc e) {
105             out.println(e);
106         }
107     }
108
109     public void run() {
110         try {
111             // Skip handshake.
112
int handshakeLength;
113
114             handshakeLength= handshakeBytes.length;
115             while (handshakeLength-- > 0) {
116                 int b= fDataIn.read();
117                 fDataOut.write(b);
118             }
119             fDataOut.flush();
120
121             // Print all packages.
122
while (true) {
123                 JdwpPacket p= JdwpPacket.read(fDataIn);
124                 // we need to store conversation only for command send by the debugger,
125
// as there is no answer from the debugger to VM commands.
126
if (!(fVMtoDebugger && (p.getFlags() & JdwpPacket.FLAG_REPLY_PACKET) == 0)) {
127                     store(p);
128                 }
129                 out.print(p, fVMtoDebugger);
130                 out.flush();
131                 p.write(fDataOut);
132                 fDataOut.flush();
133             }
134         } catch (EOFException JavaDoc e) {
135         } catch (SocketException JavaDoc e) {
136         } catch (IOException JavaDoc e) {
137             out.println(MessageFormat.format("Caught exception: {0}", new String JavaDoc[] {e.toString()})); //$NON-NLS-1$
138
e.printStackTrace(out);
139         } finally {
140             try {
141                 fDataIn.close();
142                 fDataOut.close();
143             } catch (IOException JavaDoc e) {
144             }
145             out.flush();
146         }
147     }
148
149     public static JdwpCommandPacket getCommand(int id) {
150         JdwpConversation conversation= (JdwpConversation) fPackets.get(new Integer JavaDoc(id));
151         if (conversation != null)
152             return conversation.getCommand();
153         return null;
154     }
155
156     protected static void store(JdwpPacket packet) {
157         int id= packet.getId();
158         JdwpConversation conversation= (JdwpConversation) fPackets.get(new Integer JavaDoc(id));
159         if (conversation == null) {
160             conversation= new JdwpConversation(id);
161             fPackets.put(new Integer JavaDoc(id), conversation);
162         }
163
164         if ((packet.getFlags() & JdwpPacket.FLAG_REPLY_PACKET) != 0) {
165             conversation.setReply((JdwpReplyPacket) packet);
166         } else {
167             conversation.setCommand((JdwpCommandPacket) packet);
168         }
169     }
170
171     public static int getCommand(JdwpPacket packet) throws UnableToParseDataException {
172         JdwpCommandPacket command= null;
173         if (packet instanceof JdwpCommandPacket) {
174             command= (JdwpCommandPacket) packet;
175         } else {
176             command= getCommand(packet.getId());
177             if (command == null) {
178                 throw new UnableToParseDataException("This packet is marked as reply, but there is no command with the same id.", null); //$NON-NLS-1$
179
}
180         }
181         return command.getCommand();
182     }
183
184     public static boolean hasSizes() {
185         return fHasSizes;
186     }
187
188     public static void setHasSizes(boolean value) {
189         fHasSizes= value;
190     }
191
192     public static void setFieldIDSize(int fieldIDSize) {
193         fFieldIDSize= fieldIDSize;
194     }
195
196     public static int getFieldIDSize() {
197         return fFieldIDSize;
198     }
199
200     public static void setMethodIDSize(int methodIDSize) {
201         fMethodIDSize= methodIDSize;
202     }
203
204     public static int getMethodIDSize() {
205         return fMethodIDSize;
206     }
207
208     public static void setObjectIDSize(int objectIDSize) {
209         fObjectIDSize= objectIDSize;
210     }
211
212     public static int getObjectIDSize() {
213         return fObjectIDSize;
214     }
215
216     public static void setReferenceTypeIDSize(int referenceTypeIDSize) {
217         fReferenceTypeIDSize= referenceTypeIDSize;
218     }
219
220     public static int getReferenceTypeIDSize() {
221         return fReferenceTypeIDSize;
222     }
223
224     public static void setFrameIDSize(int frameIDSize) {
225         fFrameIDSize= frameIDSize;
226     }
227
228     public static int getFrameIDSize() {
229         return fFrameIDSize;
230     }
231 }
232
Popular Tags