xmodem java_在Java中实现Xmodem协议

如何使用XMODEM协议通过Java中的串行端口接收文件?

解决方法:

这里是.

我在JModem source中找到了这个.如果你看看它写出数据的位置,你可以看到它做了SOH,blocknum,~blocknum,数据和校验和.它使用128的扇区大小.这些组合在一起构成标准XModem protocol.它也很简单,可以从这里执行XModem1K,YModem和ZModem.

/**

* 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%mit-oz@mit-mc.arpa.

* @author Java version by Ian F. Darwin, ian@darwinsys.com

* $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

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));

}

}

标签:java,protocols,xmodem

来源: https://codeday.me/bug/20190926/1819390.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值