2009-03-03 10 views
1

Ich möchte eine Datei von der seriellen Schnittstelle erhalten und ich muss verwenden, dass X-Modem-Protokoll entwickelt wurde, um eine Datei über die serielle Schnittstelle in Java zu empfangen. Wenn also irgendjemand eine Idee haben kann dann hilf mir. Ich bin in sehr viel Mühe.plzImplementierung von X-Modem-Protokoll in Java

Antwort

1

SerialIO hat eine kommerzielle Umsetzung.

+0

ich muss meinen eigenen Code entwickeln.ist dort irgendein API availabe? –

1

Nun ... Lesen Sie einfach the specs, und implementieren Sie es. Es sieht nicht allzu schwierig aus, obwohl es im Allgemeinen schwierig sein kann, auf Byteebene in Java herumzustöbern.

Ich habe nicht viel nach vorhandenen Implementierungen gesucht, ich bin mir sicher, dass es mehr gibt als die kommerzielle, die von kiannakakis vorgeschlagen wird, gibt es normalerweise. :) Ansonsten vielleicht einen Schritt zurück, und erhalten Sie einige C-Quelle, um in Java zu schauen und neu zu implementieren (Lizenz erlaubt, natürlich).

4

Hier ist es.

Ich fand dies in der JModem source. Wenn Sie sich ansehen, wo die Daten ausgegeben werden, können Sie sehen, wie SOH, blocknum, ~ blocknum, data und checksum ausgeführt werden. Es verwendet eine Sektorgröße von 128. Diese zusammen bilden den Standard XModem protocol. Es ist einfach genug, um XModem1K, YModem und ZModem auch von hier aus zu tun.

/** 
* a tiny version of Ward Christensen's MODEM program for UNIX. 
* Written ~ 1980 by Andrew Scott Beals. Last revised 1982. 
* A.D. 2000 - dragged from the archives for use in Java Cookbook. 
* 
* @author C version by Andrew Scott Beals, sjobrg.andy%[email protected] 
* @author Java version by Ian F. Darwin, [email protected] 
* $Id: TModem.java,v 1.8 2000/03/02 03:40:50 ian Exp $ 
*/ 
class TModem { 

    protected final byte CPMEOF = 26;  /* control/z */ 
    protected final int MAXERRORS = 10;  /* max times to retry one block */ 
    protected final int SECSIZE = 128;  /* cpm sector, transmission block */ 
    protected final int SENTIMOUT = 30;  /* timeout time in send */ 
    protected final int SLEEP = 30;  /* timeout time in recv */ 

    /* Protocol characters used */ 

    protected final byte SOH = 1; /* Start Of Header */ 
    protected final byte EOT = 4; /* End Of Transmission */ 
    protected final byte ACK = 6; /* ACKnowlege */ 
    protected final byte NAK = 0x15; /* Negative AcKnowlege */ 

    protected InputStream inStream; 
    protected OutputStream outStream; 
    protected PrintWriter errStream; 

    /** Construct a TModem */ 
    public TModem(InputStream is, OutputStream os, PrintWriter errs) { 
     inStream = is; 
     outStream = os; 
     errStream = errs; 
    } 

    /** Construct a TModem with default files (stdin and stdout). */ 
    public TModem() { 
     inStream = System.in; 
     outStream = System.out; 
     errStream = new PrintWriter(System.err); 
    } 

    /** A main program, for direct invocation. */ 
    public static void main(String[] argv) throws 
     IOException, InterruptedException { 

     /* argc must == 2, i.e., `java TModem -s filename' */ 
     if (argv.length != 2) 
      usage(); 

     if (argv[0].charAt(0) != '-') 
      usage(); 

     TModem tm = new TModem(); 
     tm.setStandalone(true); 

     boolean OK = false; 
     switch (argv[0].charAt(1)){ 
     case 'r': 
      OK = tm.receive(argv[1]); 
      break; 
     case 's': 
      OK = tm.send(argv[1]); 
      break; 
     default: 
      usage(); 
     } 
     System.out.print(OK?"Done OK":"Failed"); 
     System.exit(0); 
    } 

    /* give user minimal usage message */ 
    protected static void usage() 
    { 
     System.err.println("usage: TModem -r/-s file"); 
     // not errStream, not die(), since this is static. 
     System.exit(1); 
    } 

    /** If we're in a standalone app it is OK to System.exit() */ 
    protected boolean standalone = false; 
    public void setStandalone(boolean is) { 
     standalone = is; 
    } 
    public boolean isStandalone() { 
     return standalone; 
    } 

    /** A flag used to communicate with inner class IOTimer */ 
    protected boolean gotChar; 

    /** An inner class to provide a read timeout for alarms. */ 
    class IOTimer extends Thread { 
     String message; 
     long milliseconds; 

     /** Construct an IO Timer */ 
     IOTimer(long sec, String mesg) { 
      milliseconds = 1000 * sec; 
      message = mesg; 
     } 

     public void run() { 
      try { 
      Thread.sleep(milliseconds); 
      } catch (InterruptedException e) { 
      // can't happen 
      } 
      /** Implement the timer */ 
      if (!gotChar) 
      errStream.println("Timed out waiting for " + message); 
      die(1); 
     } 
    } 

    /* 
    * send a file to the remote 
    */ 
    public boolean send(String tfile) throws IOException, InterruptedException 
    { 
     char checksum, index, blocknumber, errorcount; 
     byte character; 
     byte[] sector = new byte[SECSIZE]; 
     int nbytes; 
     DataInputStream foo; 

     foo = new DataInputStream(new FileInputStream(tfile)); 
     errStream.println("file open, ready to send"); 
     errorcount = 0; 
     blocknumber = 1; 

     // The C version uses "alarm()", a UNIX-only system call, 
     // to detect if the read times out. Here we do detect it 
     // by using a Thread, the IOTimer class defined above. 
     gotChar = false; 
     new IOTimer(SENTIMOUT, "NAK to start send").start(); 

     do { 
      character = getchar(); 
      gotChar = true; 
      if (character != NAK && errorcount < MAXERRORS) 
       ++errorcount; 
     } while (character != NAK && errorcount < MAXERRORS); 

     errStream.println("transmission beginning"); 
     if (errorcount == MAXERRORS) { 
      xerror(); 
     } 

     while ((nbytes=inStream.read(sector))!=0) { 
      if (nbytes<SECSIZE) 
       sector[nbytes]=CPMEOF; 
      errorcount = 0; 
      while (errorcount < MAXERRORS) { 
       errStream.println("{" + blocknumber + "} "); 
       putchar(SOH); /* here is our header */ 
       putchar(blocknumber); /* the block number */ 
       putchar(~blocknumber); /* & its complement */ 
       checksum = 0; 
       for (index = 0; index < SECSIZE; index++) { 
        putchar(sector[index]); 
        checksum += sector[index]; 
       } 
       putchar(checksum); /* tell our checksum */ 
       if (getchar() != ACK) 
        ++errorcount; 
       else 
        break; 
      } 
      if (errorcount == MAXERRORS) 
       xerror(); 
      ++blocknumber; 
     } 
     boolean isAck = false; 
     while (!isAck) { 
      putchar(EOT); 
      isAck = getchar() == ACK; 
     } 
     errStream.println("Transmission complete."); 
     return true; 
    } 

    /* 
    * receive a file from the remote 
    */ 
    public boolean receive(String tfile) throws IOException, InterruptedException 
    { 
     char checksum, index, blocknumber, errorcount; 
     byte character; 
     byte[] sector = new byte[SECSIZE]; 
     DataOutputStream foo; 

     foo = new DataOutputStream(new FileOutputStream(tfile)); 

     System.out.println("you have " + SLEEP + " seconds..."); 

     /* wait for the user or remote to get his act together */ 
     gotChar = false; 
     new IOTimer(SLEEP, "receive from remote").start(); 

     errStream.println("Starting receive..."); 
     putchar(NAK); 
     errorcount = 0; 
     blocknumber = 1; 
     rxLoop: 
     do { 
      character = getchar(); 
      gotChar = true; 
      if (character != EOT) { 
       try { 
        byte not_ch; 
        if (character != SOH) { 
         errStream.println("Not SOH"); 
         if (++errorcount < MAXERRORS) 
          continue rxLoop; 
         else 
          xerror(); 
        } 
        character = getchar(); 
        not_ch = (byte)(~getchar()); 
        errStream.println("[" + character + "] "); 
        if (character != not_ch) { 
         errStream.println("Blockcounts not ~"); 
         ++errorcount; 
         continue rxLoop; 
        } 
        if (character != blocknumber) { 
         errStream.println("Wrong blocknumber"); 
         ++errorcount; 
         continue rxLoop; 
        } 
        checksum = 0; 
        for (index = 0; index < SECSIZE; index++) { 
         sector[index] = getchar(); 
         checksum += sector[index]; 
        } 
        if (checksum != getchar()) { 
         errStream.println("Bad checksum"); 
         errorcount++; 
         continue rxLoop; 
        } 
        putchar(ACK); 
        blocknumber++; 
        try { 
         foo.write(sector); 
        } catch (IOException e) { 
         errStream.println("write failed, blocknumber " + blocknumber); 
        } 
       } finally { 
       if (errorcount != 0) 
        putchar(NAK); 
      } 
     } 
     } while (character != EOT); 

     foo.close(); 

     putchar(ACK); /* tell the other end we accepted his EOT */ 
     putchar(ACK); 
     putchar(ACK); 

     errStream.println("Receive Completed."); 
     return true; 
    } 

    protected byte getchar() throws IOException { 
     return (byte)inStream.read(); 
    } 

    protected void putchar(int c) throws IOException { 
     outStream.write(c); 
    } 

    protected void xerror() 
    { 
     errStream.println("too many errors...aborting"); 
     die(1); 
    } 

    protected void die(int how) 
    { 
     if (standalone) 
      System.exit(how); 
     else 
      System.out.println(("Error code " + how)); 
    } 
} 
+0

@sumesh hat das für Sie funktioniert? –

0

Funktioniert dieses Programm wirklich? Ich versuche es zu benutzen, aber ich bekomme die ganze Zeit eine Ausnahme. Im Sende-Teil verwendet der Code den Dateinamen überhaupt nicht ...

Wenn Sie JModem verwenden, wenn Sie den Transfer-Button anklicken, erhält das andere Ende die Zeichenfolge "tmodem -r at.ht" oder - s wenn Sie empfangen. Aber ich sehe dieses Ende nichts mit der Schnur ... es wird nur auf dem Textbereich gezeigt ...