Fields Summary |
---|
private static Object | syncA synchronisation object. It's used for synchronising access
to finished field. |
private static Object | sync1A synchronication object. Using this object a reading
loop waits for invoking receive() method. |
private static Object | sync2A synchronisation object. It's used for synchronising access
to the buffer that contains data that already read and to the
cycleStarted field. |
private String | serverNameA host name where VM being debugged is running. |
private int | portNumberA TCP/IP port number that is used for connecting to VM being debugged. |
private boolean | finishedIndicates that it's time to finish this thread. May be initiated inside
and outside the thread. |
private DataInputStream | inputStreamA stream that reads data from the socket. |
private DataOutputStream | outputStreamA stream that writes data to the socket. |
private Socket | socketA socket that provides JDWP connection. |
private Vector | repliesA reference to the outer object ahere is to put
an information about received JDWP replies. |
private Vector | repliesInternalAn internal structure for temporary keeping of received JDWP
replies. Later this data is copied to replies vector. |
private int | expectedSizeIf this field is set to -1 a normal JDWP packet
is expected. Otherwise it indicates that handshake is expected and
is value equals to expected size of handshake string. |
private int | currentInPrivateBufferA current position in the buffer that contains received handshake
string. |
private int | handShakeSizeAn expected size of received handshake string. |
private byte[] | privateBufferA buffer that contains a received handshake string. |
private boolean | cycleStartedIndicates that the reading thread doesn't sleep but processes reading
of data. Used by handshake procedure to wait until receiving handshake
string. |
Methods Summary |
---|
public void | attachToServer()Establishes TCP/IP connection to the VM being debugged.
NOTE: It's one of few methods in KJDB that produces non-debug
output directly. It's not good. For non-debug output classes
must use kdb.Log class. So may be it's a good idea
to remove the message this method prints.
socket = new Socket(serverName, portNumber);
Tools.wait(100);
System.out.println("Socket Created.");
socket.setTcpNoDelay(true);
inputStream = new DataInputStream(socket.getInputStream());
outputStream = new DataOutputStream(socket.getOutputStream());
|
public int | availableInPrivateBuffer()Returns the number of bytes that are available in the buffer
that that contains received handshake string.
synchronized(sync){
if(finished){
throw new SocketException("Connection closed");
}
}
//System.out.println("available");
synchronized(sync2){
if(expectedSize == -1){
return handShakeSize;
}else{
return 0;
}
}
|
public void | done()This method sets the finished field that
indicates that the background thread is to be finished.
After this it closes JDWP connection.
synchronized(sync){
finished = true;
}
doneInternal();
|
private synchronized void | doneInternal()Internal method that terminates JDWP connection in fact.
try{
if(socket == null){
return;
}
socket.close();
}catch(IOException e){
}
|
public void | initAsClient(java.lang.String serverName, int portNumber, java.util.Vector replies)Intializes some internal fields of the object. Need to be invoked
immediately after constructor.
this.serverName = serverName;
this.portNumber = portNumber;
this.replies = replies;
|
public boolean | isStarted()Checks if the background thread is initialized and is not received
request for terminating yet.
synchronized(sync){
return !finished;
}
|
public int | readNextFromPrivateBuffer()Reads next byte from the buffer that contains received
handshake string.
synchronized(sync){
if(finished){
throw new SocketException("Connection closed");
}
}
//System.out.println("read");
synchronized(sync2){
return privateBuffer[currentInPrivateBuffer++];
}
|
public void | receive()Stores a portion of received replies in the outer buffer. If no replies
are received since the previous call of this method it does nothing.
//System.out.println("receive");
synchronized(sync){
if(finished){
throw new SocketException("Connection closed");
}
}
synchronized(sync1){
sync1.notifyAll();
}
synchronized(repliesInternal){
replies.addAll(repliesInternal);
repliesInternal.clear();
}
|
public void | run()It's an entry point of background thread. This method processes
reading of handshake and normal JDWP packets and stores the received
values in repliesInternal vector.
Also this method establishes JDWP connection.
The method works in a
loop until finished field becomes true .
After this the JDWP connections terminates.
//setPriority(MIN_PRIORITY);
synchronized(sync){
finished = false;
}
byte[] buf = new byte[100000];
try{
attachToServer();
boolean timeToQuit = false;
synchronized(sync){
timeToQuit = finished;
}
synchronized(this){
notifyAll();
}
while(!timeToQuit){
synchronized(sync1){
sync1.wait();
}
synchronized(sync2){
cycleStarted = true;
}
if(expectedSize != -1){
//read handshake
int bytesRead = 0;
while(bytesRead != expectedSize){
bytesRead += inputStream.read(buf, bytesRead, expectedSize - bytesRead);
}
synchronized(sync2){
for(int i=0 ; i<expectedSize ; i++){
privateBuffer[i] = buf[i];
}
expectedSize = -1;
}
continue;
}
//System.out.println("read packet");
//Read header
int bytesRead = 0;
while(bytesRead != Packet.PacketHeaderSize){
int bytesReadDuringLastRead = inputStream.read(buf,
bytesRead, Packet.PacketHeaderSize - bytesRead);
bytesRead += bytesReadDuringLastRead;
if(bytesReadDuringLastRead == -1){
throw new IOException("Connection closed");
}
}
//System.out.println("read data");
//Read data
int size = (((((int)buf[0]) & 0xFF) << 24) |
((((int)buf[1]) & 0xFF ) << 16) |
((((int)buf[2]) & 0xFF ) << 8) |
(((int)buf[3]) & 0xFF));
bytesRead = 0;
while(bytesRead != size - Packet.PacketHeaderSize){
int bytesReadDuringLastRead =
inputStream.read(buf, bytesRead + Packet.PacketHeaderSize,
size - Packet.PacketHeaderSize - bytesRead);
bytesRead += bytesReadDuringLastRead;
if(bytesReadDuringLastRead == -1){
throw new IOException("Connection closed");
}
}
//System.out.println("data read");
Reply r = new Reply();
r.resetBuffer();
r.addBytes(buf,0,size);
synchronized(repliesInternal){
repliesInternal.add(r);
}
synchronized(sync){
timeToQuit = finished;
}
}
}catch(IOException e){
synchronized(sync){
finished = true;
}
synchronized(this){
notifyAll();
}
}catch(InterruptedException e){
synchronized(sync){
finished = true;
}
synchronized(this){
notifyAll();
}
}
synchronized(sync){
finished = true;
}
doneInternal();
|
public void | startHandShake(int len)Initiates handshake procedure that is physically performed
by run() method and waits for run()
method's sterting the waiting for reply. After this it exits.
This procedure is performed immediately after establishing TCP/IP
connection and consist on sending and receiving "JDWP-Handshake" string.
currentInPrivateBuffer = 0;
expectedSize = len;
handShakeSize = len;
boolean b = true;
do{
synchronized(sync1){
sync1.notifyAll();
}
synchronized(sync2){
b = !cycleStarted;
}
}while(b);
synchronized(sync2){
cycleStarted = false;
}
|
public void | write(int b)Writes a specified byte into the socket.
outputStream.write(b);
//System.out.println("Written byte " + b);
|