Telnet协议的java实现

Telnet协议的java实现

//telnet.java

import java.net.Socket;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.awt.Dimension;
import java.util.Vector;

class TelnetIO
{

//0 is close, 1 is connet,2 is login
    private String estring="";
private  int isconn = 0;
public  int timeout = 50000;
    private  String tmpmess="";
    public String showe()
{
return estring;
}
public int nowstate()
{
return isconn;
}


public String showmess()
{
return tmpmess;
}
//login 1 is login,0 time out,-1 Exception,-2 passwd is error
  public  int login(String user,String passwd)
  {
      int error;

      error=waits("ogin:");
  if (error<1){return error;}
      error=sends(user);
    if (error<1){return error;}
      error=waits("assword:");
    if (error<1){return error;}
      error=sends(passwd);
    if (error<1){return error;}
      error=waits("$");
  if (error<1){return error;}
      isconn=2;
   return 1;

  }
  public  int sends(String str)
  {
    byte[] buf = new byte[str.length()];
    str.getBytes(0, str.length(), buf, 0);
    try { send(buf); } catch(IOException e) {estring=e.toString();return -1;}
return 1;
  }
  public  int  waits(String prompt)
  {

String tmp = "";
    tmpmess=tmp;
int nt=1;
    do {
      try { tmp = new String(receive(), 0); }
      catch(Exception e) { estring=e.toString();return -1; }
  nt=nt+1;
  if (nt>timeout){return 0; }
           if (tmp.length()>0)
            {
  tmpmess=tmp;
//              System.out.println("1");
//   System.out.print(tmp);
  }
  if (prompt.equals("$") && (tmp.indexOf("Login incorrect")!=-1) )
  {
  estring="Login incorrect";
  return -2;
  }


    } while(tmp.indexOf(prompt) == -1);
    return 1;
  }
  public  int  waits( )
  {

String tmp = "";
    tmpmess=tmp;
int nt=1;
    do {
      try { tmp = new String(receive(), 0); }
      catch(Exception e) { return -1; }
  nt=nt+1;
  if (nt>timeout){return 0; }
           if (tmp.length()>0)
            { tmpmess=tmp;}


    } while(tmp.length()==0);
    return 1;
  }

 


/**
* Debug level. This results in additional diagnostic messages on the
* java console.
*/
private static int debug = 0;


/**
* State variable for telnetnegotiation reader
*/
private byte neg_state = 0;

/**
* constants for the negotiation state
*/
private final static byte STATE_DATA = 0;
private final static byte STATE_IAC = 1;
private final static byte STATE_IACSB = 2;
private final static byte STATE_IACWILL = 3;
private final static byte STATE_IACDO = 4;
private final static byte STATE_IACWONT = 5;
private final static byte STATE_IACDONT = 6;
private final static byte STATE_IACSBIAC = 7;
private final static byte STATE_IACSBDATA = 8;
private final static byte STATE_IACSBDATAIAC = 9;

/**
* What IAC SB <xx> we are handling right now
*/
private byte current_sb;

/**
* IAC - init sequence for telnet negotiation.
*/
private final static byte IAC  = (byte)255;
/** FF
* [IAC] End Of Record
*/
private final static byte EOR  = (byte)239;
/** EF
* [IAC] WILL
*/
private final static byte WILL  = (byte)251;
/** FB
* [IAC] WONT
*/
private final static byte WONT  = (byte)252;
/** FC
* [IAC] DO
*/
private final static byte DO    = (byte)253;
/**FD
* [IAC] DONT
*/
private final static byte DONT  = (byte)254;
/**FE
* [IAC] Sub Begin
*/
private final static byte SB  = (byte)250;
/** FA
* [IAC] Sub End
*/
private final static byte SE  = (byte)240;
/** FO
* Telnet option: echo text
*/
private final static byte TELOPT_ECHO  = (byte)1;  /* echo on/off */
/** 1
* Telnet option: End Of Record
*/
private final static byte TELOPT_EOR   = (byte)25;  /* end of record */
/** 19
* Telnet option: Negotiate About Window Size
*/
private final static byte TELOPT_NAWS  = (byte)31;  /* NA-WindowSize*/
/** 1F
* Telnet option: Terminal Type
*/
private final static byte TELOPT_TTYPE  = (byte)24;  /* terminal type */
   //18
private final static byte[] IACWILL  = { IAC, WILL };
private final static byte[] IACWONT  = { IAC, WONT };
private final static byte[] IACDO    = { IAC, DO };
private final static byte[] IACDONT  = { IAC, DONT };
private final static byte[] IACSB  = { IAC, SB };
private final static byte[] IACSE  = { IAC, SE };

/**
* Telnet option qualifier 'IS'
*/
private final static byte TELQUAL_IS = (byte)0;

/**
* Telnet option qualifier 'SEND'
*/
private final static byte TELQUAL_SEND = (byte)1;

/**
* What IAC DO(NT) request do we have received already ?
*/
        private byte[] receivedDX;

/**
* What IAC WILL/WONT request do we have received already ?
*/
private byte[] receivedWX;
/**
* What IAC DO/DONT request do we have sent already ?
*/
private byte[] sentDX;
/**
* What IAC WILL/WONT request do we have sent already ?
*/
private byte[] sentWX;

private Socket socket;
private BufferedInputStream is;
private BufferedOutputStream os;

// private StatusPeer peer = this; /* peer, notified on status */

/**
* Connect to the remote host at the specified port.
* @param address the symbolic host address
* @param port the numeric port
* @see #disconnect
*/
public void connect(String address, int port) throws IOException {
if(debug > 0) System.out.println("Telnet.connect("+address+","+port+")");
socket = new Socket(address, port);
is = new BufferedInputStream(socket.getInputStream());
os = new BufferedOutputStream(socket.getOutputStream());
neg_state = 0;
isconn=1;
receivedDX = new byte[256];
sentDX = new byte[256];
receivedWX = new byte[256];
sentWX = new byte[256];
}

/**
* Disconnect from remote host.
* @see #connect
*/
public void disconnect() throws IOException {
  if(debug > 0) System.out.println("TelnetIO.disconnect()");
  if(socket !=null) socket.close();
}

/**
* Connect to the remote host at the default telnet port (23).
* @param address the symbolic host address
*/
public void connect(String address) throws IOException {
connect(address, 23);
}

/**
* Set the object to be notified about current status.
* @param obj object to be notified.
*/
// public void setPeer(StatusPeer obj) { peer = obj; }

/** Returns bytes available to be read.  Since they haven't been
* negotiated over, this could be misleading.
* Most useful as a boolean value - "are any bytes available" -
* rather than as an exact count of "how many ara available."
*
* @exception IOException on problems with the socket connection
*/
public int available() throws IOException
{
  return is.available();
}


/**
* Read data from the remote host. Blocks until data is available.
* Returns an array of bytes.
* @see #send
*/
public byte[] receive() throws IOException {
int count = is.available();

byte buf[] = new byte[count];
count = is.read(buf);
if(count < 0) throw new IOException("Connection closed.");
if(debug > 1) System.out.println("TelnetIO.receive(): read bytes: "+count);
buf = negotiate(buf, count);
return buf;
}

/**
* Send data to the remote host.
* @param buf array of bytes to send
* @see #receive
*/
public void send(byte[] buf) throws IOException {
if(debug > 1) System.out.println("TelnetIO.send("+buf+")");
os.write(buf);
os.flush();
}

public void send(byte b) throws IOException {
if(debug > 1) System.out.println("TelnetIO.send("+b+")");
os.write(b);
os.flush();
}

/**
* Handle an incoming IAC SB <type> <bytes> IAC SE
* @param type type of SB
* @param sbata byte array as <bytes>
* @param sbcount nr of bytes. may be 0 too.
*/

private void handle_sb(byte type, byte[] sbdata, int sbcount)
throws IOException
{
if(debug > 1)
System.out.println("TelnetIO.handle_sb("+type+")");
switch (type) {
case TELOPT_TTYPE:
if (sbcount>0 && sbdata[0]==TELQUAL_SEND) {
String ttype;
send(IACSB);send(TELOPT_TTYPE);send(TELQUAL_IS);
/* FIXME: need more logic here if we use
* more than one terminal type
*/
Vector vec = new Vector(2);
vec.addElement("TTYPE");
                ttype=null;
if(ttype == null) ttype = "dumb";
byte[] bttype = new byte[ttype.length()];

ttype.getBytes(0,ttype.length(), bttype, 0);
send(bttype);
send(IACSE);
}

}
}

/**
* Notify about current telnet status. This method is called top-down.
* @param status contains status information
*/
public Object notifyStatus(Vector status) {
if(debug > 0)
  System.out.println("TelnetIO.notifyStatus("+status+")");
  isconn=0;
return null;
}

/* wo faengt buf an bei buf[0] oder bei buf[1] */
private byte[] negotiate(byte buf[], int count) throws IOException {
if(debug > 1)
System.out.println("TelnetIO.negotiate("+buf+","+count+")");
byte nbuf[] = new byte[count];
byte sbbuf[] = new byte[count];
byte sendbuf[] = new byte[3];
byte b,reply;
int  sbcount = 0;
int boffset = 0, noffset = 0;
Vector vec = new Vector(2);

while(boffset < count) {
b=buf[boffset++];
/* of course, byte is a signed entity (-128 -> 127)
* but apparently the SGI Netscape 3.0 doesn't seem
* to care and provides happily values up to 255
*/
if (b>=128)
b=(byte)((int)b-256);
switch (neg_state) {
case STATE_DATA:
if (b==IAC) {
neg_state = STATE_IAC;
} else {
nbuf[noffset++]=b;
}
break;
case STATE_IAC:
switch (b) {
case IAC:
if(debug > 2)
System.out.print("IAC ");
neg_state = STATE_DATA;
nbuf[noffset++]=IAC;
break;
case WILL:
if(debug > 2)
System.out.print("WILL ");
neg_state = STATE_IACWILL;
break;
case WONT:
if(debug > 2)
System.out.print("WONT ");
neg_state = STATE_IACWONT;
break;
case DONT:
if(debug > 2)
System.out.print("DONT ");
neg_state = STATE_IACDONT;
break;
case DO:
if(debug > 2)
System.out.print("DO ");
neg_state = STATE_IACDO;
break;
case EOR:
if(debug > 2)
System.out.print("EOR ");
neg_state = STATE_DATA;
break;
case SB:
if(debug > 2)
System.out.print("SB ");
neg_state = STATE_IACSB;
sbcount = 0;
break;
default:
if(debug > 2)
System.out.print(
"<UNKNOWN "+b+" > "
);
neg_state = STATE_DATA;
break;
}
break;
case STATE_IACWILL:
switch(b) {
case TELOPT_ECHO:
if(debug > 2)
System.out.println("ECHO");
reply = DO;
vec = new Vector(2);
vec.addElement("NOLOCALECHO");
// peer.notifyStatus(vec);
break;
case TELOPT_EOR:
if(debug > 2)
System.out.println("EOR");
reply = DO;
break;
default:
if(debug > 2)
System.out.println(
"<UNKNOWN,"+b+">"
);
reply = DONT;
break;
}
if(debug > 1)
  System.out.println("<"+b+", WILL ="+WILL+">");
if ( reply != sentDX[b+128] ||
WILL != receivedWX[b+128]
) {
sendbuf[0]=IAC;
sendbuf[1]=reply;
sendbuf[2]=b;
send(sendbuf);
sentDX[b+128] = reply;
receivedWX[b+128] = WILL;
}
neg_state = STATE_DATA;
break;
case STATE_IACWONT:
switch(b) {
case TELOPT_ECHO:
if(debug > 2)
System.out.println("ECHO");

vec = new Vector(2);
// vec.addElement("LOCALECHO");
reply = DONT;
break;
case TELOPT_EOR:
if(debug > 2)
System.out.println("EOR");
reply = DONT;
break;
default:
if(debug > 2)
System.out.println(
"<UNKNOWN,"+b+">"
);
reply = DONT;
break;
}
if ( reply != sentDX[b+128] ||
WONT != receivedWX[b+128]
) {
sendbuf[0]=IAC;
sendbuf[1]=reply;
sendbuf[2]=b;
send(sendbuf);
sentDX[b+128] = reply;
receivedWX[b+128] = WILL;
}
neg_state = STATE_DATA;
break;
case STATE_IACDO:
switch (b) {
case TELOPT_ECHO:
if(debug > 2)
System.out.println("ECHO");
reply = WILL;
vec = new Vector(2);
vec.addElement("LOCALECHO");
// peer.notifyStatus(vec);
break;
case TELOPT_TTYPE:
if(debug > 2)
System.out.println("TTYPE");
reply = WILL;
break;
case TELOPT_NAWS:
if(debug > 2)
System.out.println("NAWS");
vec = new Vector(2);
vec.addElement("NAWS");
//******************************************************

// Dimension size = (Dimension)

// peer.notifyStatus(vec);
receivedDX[b] = DO;
Dimension size=null;
if(size == null)
{
/* this shouldn't happen */
send(IAC);
send(WONT);
send(TELOPT_NAWS);
reply = WONT;
sentWX[b] = WONT;
break;
}
reply = WILL;
sentWX[b] = WILL;
sendbuf[0]=IAC;
sendbuf[1]=WILL;
sendbuf[2]=TELOPT_NAWS;
send(sendbuf);
send(IAC);send(SB);send(TELOPT_NAWS);
send((byte) (size.width >> 8));
send((byte) (size.width & 0xff));
send((byte) (size.height >> 8));
send((byte) (size.height & 0xff));
send(IAC);send(SE);
break;
default:
if(debug > 2)
System.out.println(
"<UNKNOWN,"+b+">"
);
reply = WONT;
break;
}
if ( reply != sentWX[128+b] ||
DO != receivedDX[128+b]
) {
sendbuf[0]=IAC;
sendbuf[1]=reply;
sendbuf[2]=b;
send(sendbuf);
sentWX[b+128] = reply;
receivedDX[b+128] = DO;
}
neg_state = STATE_DATA;
break;
case STATE_IACDONT:
switch (b) {
case TELOPT_ECHO:
if(debug > 2)
System.out.println("ECHO");
reply = WONT;
vec = new Vector(2);
vec.addElement("NOLOCALECHO");
// peer.notifyStatus(vec);
break;
case TELOPT_NAWS:
if(debug > 2)
System.out.println("NAWS");
reply = WONT;
break;
default:
if(debug > 2)
System.out.println(
"<UNKNOWN,"+b+">"
);
reply = WONT;
break;
}
if ( reply != sentWX[b+128] ||
DONT != receivedDX[b+128]
) {
send(IAC);send(reply);send(b);
sentWX[b+128] = reply;
receivedDX[b+128] = DONT;
}
neg_state = STATE_DATA;
break;
case STATE_IACSBIAC:
if(debug > 2) System.out.println(""+b+" ");
if (b == IAC) {
sbcount = 0;
current_sb = b;
neg_state = STATE_IACSBDATA;
} else {
System.out.println("(bad) "+b+" ");
neg_state = STATE_DATA;
}
break;
case STATE_IACSB:
if(debug > 2) System.out.println(""+b+" ");
switch (b) {
case IAC:
neg_state = STATE_IACSBIAC;
break;
default:
current_sb = b;
sbcount = 0;
neg_state = STATE_IACSBDATA;
break;
}
break;
case STATE_IACSBDATA:
if (debug > 2) System.out.println(""+b+" ");
switch (b) {
case IAC:
neg_state = STATE_IACSBDATAIAC;
break;
default:
sbbuf[sbcount++] = b;
break;
}
break;
case STATE_IACSBDATAIAC:
if (debug > 2) System.out.println(""+b+" ");
switch (b) {
case IAC:
neg_state = STATE_IACSBDATA;
sbbuf[sbcount++] = IAC;
break;
case SE:
handle_sb(current_sb,sbbuf,sbcount);
current_sb = 0;
neg_state = STATE_DATA;
break;
case SB:
handle_sb(current_sb,sbbuf,sbcount);
neg_state = STATE_IACSB;
break;
default:
neg_state = STATE_DATA;
break;
}
break;
default:
if (debug > 2)
System.out.println(
"This should not happen: "+
neg_state+" "
);
neg_state = STATE_DATA;
break;
}
}
buf = new byte[noffset];
System.arraycopy(nbuf, 0, buf, 0, noffset);
return buf;
}
}
class  Telnet2
{

  public static void main(String args[])
  {
    TelnetIO tio = new TelnetIO();
    int nnn;
try {
      tio.connect("59.64.156.145");//在此输入欲登陆的主机名
      nnn=tio.login("test\r","test\r");//用户名和密码
  if (nnn!=1)
  {
  System.out.println("error login ");
  return ;
  }
  System.out.print(tio.showmess());
      tio.sends("ls\r");
  do
  {  nnn=tio.waits();
    if (nnn==1){System.out.print(tio.showmess());}
  }while (nnn==1);
      tio.sends("rm ss\r");
  do
  {  nnn=tio.waits();
    if (nnn==1){System.out.print(tio.showmess());}
  }while (nnn==1);

    } catch(IOException e) { System.out.println(e); }

  }
}

posted @ 2013-01-30 13:29  叶川  阅读(3705)  评论(0编辑  收藏  举报