2009-03-03 20 views
1

Seri bağlantı noktasından bir dosya almak istiyorum ve bu X modem protokolünü Java'da seri bağlantı noktası üzerinden bir dosya almak için kullanmak zorundayım. O zaman kimse hakkında fikir sahibi olabilirse bana yardım et. Ben çok fazla sorun yaşıyorum.Java'da X-modem protokolünün uygulanması

cevap

1

SerialIO ticari bir uygulamaya sahiptir.

+0

Kendi code.is orada API mevcut var mı? –

1

Eh ... Sadece the specs numaralı telefonu okuyun ve uygulayın. Çok zor görünmese de, genel olarak Java'da bayt seviyesinde gezinmek garip gelebilir.

Mevcut uygulamalar için çok fazla şey aramadım, eminim ki, kgiannakakis tarafından önerilen ticari olandan daha fazlası vardır, genellikle vardır. :) Aksi takdirde, belki de bir adım geri alın ve Java'ya bakmak ve yeniden uygulamak için bazı C kaynakları edinin (tabi ki izin belgesi).

4

İşte işte burada.

Bunu, JModem source numaralı belgede buldum. Verileri yazdığı yere bakarsanız, SOH, blocknum, ~ blocknum, data ve checksum yaptıklarını görebilirsiniz. 128'lik bir sektör büyüklüğünü kullanır. Bunlar birlikte XModem protocol standardını oluşturur. XModem1K, YModem ve ZModem'i burada da yapacak kadar basit.

/** 
* 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 bu işi sizin için yaptı mı? –

0

Bu program gerçekten işe yarıyor mu? Kullanmaya çalışıyorum ama her zaman bir istisna alıyorum. Gönderme bölümünde, kod hiç bir dosya adını kullanmaz ...

Eğer JModem kullanırsanız, transfer düğmesini temizlediğinizde, diğer uç "tmodem -r at.ht" dizgesini alır veya eğer alıyorsan. Ama ben bu ucunu dize ile herhangi bir şey yapmıyorum görmüyorum ... sadece metin alanı üzerinde gösterdi ...