数据传输与校验的问题?
数据格式:<STX> data <ETX> lrc
其中:
STX与ETX为控制字符,用来控制数据的传输,发送方对数据进行格式标记。STX(0x02):用于标记数据记录的开始,其后紧跟记录数据。ETX(0x03):用于标记数据记录的结束,位于数据记录之后,lrc校验码之前。data为记录数据,标准ASCII格式。lrc为校验码,产生规则:种子为0x00,然后依次与记录数据的每一字节(不包括STX)进行XOR运算,最后再与ETX进行XOR运算。运算过程中,前一次运算的结果为新的种子。
Data记录格式:一条记录数据包含多个字段,字段之间用分隔符(0x7C即’|’)分隔。其中第一个字段为记录ID,长度为两个字节。记录ID表明此记录数据的数据意义。除记录ID外,其他字段没有固定长度,以分隔符为边界(部分字段有固定格式)。
下面是相关的Data记录的详细说明及用例:
KR:请求发卡,包含字段:WS:工作站号,KC:卡片代码,RN:客房,K#:该客房内卡片序号(床号),GA:客人入住日期,GD:客人预离日期,G#:客人编号(帐号),GN:客人姓名。
例如:KR|WS3|KC1|RN2781|K#1|GA001018|GD001225|G#381921|GNQYZHAO|
表示:3号工作站请求发卡,卡片代码为1,客房为2781,日期从2000年10月18日到2000年12月25日,客人编号为381921,客人姓名为QYZHAO。
现在写一个程序,EDIT1.text写入WS:工作站号,edit2.text写入KC:卡片代码。。。edit8.text写入GN:客人姓名。当点击“确定”按钮时,在c:\text下建立一个test1.req文件(标准ASCII格式),建立一个test2.req文件(二进制格式)。
我需要源码与说明,请大家帮忙。
问题点数:200、回复次数:10Top
1 楼dzogchen(雪茹)回复于 2001-09-25 19:54:25 得分 0
upTop
2 楼guipei(IMRAD(QQ:88598744))回复于 2001-09-25 21:10:45 得分 0
数据验证还是用CRC好。。。Top
3 楼dzogchen(雪茹)回复于 2001-09-27 14:49:45 得分 0
upTop
4 楼hellion(恶人)回复于 2001-09-27 15:57:41 得分 0
有时间写那么多说明,用来写代码早写好了。为什么不自己写呢,很容易的呀。Top
5 楼Tense(何必)回复于 2001-09-27 16:20:10 得分 0
考虑Top
6 楼dzogchen(雪茹)回复于 2001-09-28 09:02:43 得分 0
ellion(恶人)
我要是会写,还贴什么帖子!
Top
7 楼dzogchen(雪茹)回复于 2001-09-30 12:15:04 得分 0
upTop
8 楼gzmhero(hihihi)回复于 2001-09-30 15:13:49 得分 0
{
这么繁的问题,我就做做好事吧。
写了这么多代码,花了我一个午休时间啊。如下代码已经调试通过。
你使用时再改改吧。
}
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons,FileCtrl;
const
MAX_BUFFER = 5*1024;/////最大缓冲区
STX = 2;
ETX = 3;
SaveFilePath = 'c:\text\';
type
TBytes=Array of Byte;
TPInteger = ^Integer;
TPDouble=^Double;
TPByte=^Byte;
TForm1 = class(TForm)
BitBtn1: TBitBtn;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure FormShow(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
function BuildPacket:integer;
procedure SaveToFile;
public
{ Public declarations }
end;
var
Form1: TForm1;
packets:TBytes;///////数据包
lrcCheck:integer;////校验码
Len:integer;///////数据包总长度
procedure WriteLongToBuf(iTemp:integer;var packets:TBytes;var index:integer);
////写一个整数到数据包
procedure WriteCharToBuf(cTemp:Char;var packets:TBytes;var index:integer);
////写一个字符到数据包
procedure WriteStringToBuf(strTemp:string;len:integer;var packets:TBytes;var index:integer);
////写一个字符串到数据包
function CalcuCheckValue(packets:TBytes;iPos,lrcCheck:integer):integer;
/////计算校验码
implementation
{$R *.DFM}
function TForm1.BuildPacket:integer;
//////按照界面上的Edit,建立数据包
var
iPos:integer;
strTemp:string;
begin
iPos:=0;
WriteCharToBuf(Char(STX),packets,iPos);
WriteStringToBuf('KR|',3,packets,iPos);
strTemp:='WS'+Edit1.Text+'|';
WriteStringToBuf(strTemp,Length(strTemp),packets,iPos);
strTemp:='KC'+Edit2.Text+'|';
WriteStringToBuf(strTemp,Length(strTemp),packets,iPos);
strTemp:='RN'+Edit3.Text+'|';
WriteStringToBuf(strTemp,Length(strTemp),packets,iPos);
{
////所有的Edit按照如上的格式写入数据包,此处只处理了3个做例子。
}
WriteCharToBuf(Char(ETX),packets,iPos);
lrcCheck:=CalcuCheckValue(packets,iPos,lrcCheck);
WriteLongToBuf(lrcCheck,packets,iPos);
Result:=iPos;
end;
procedure TForm1.SaveToFile;
/////存盘到文件
{
以下代码只按照ASCII格式写入文件,不知你说的ASCII文件和二进制文件有何要求,文件格式
没有ASCII和二进制的区别,写入可见字符就是文本文件,写入不可见字符就为二进制文件。
}
var
iFileHandle : Integer;
i:integer;
begin
if not DirectoryExists(SaveFilePath) then
if CreateDir(SaveFilePath) then
begin
iFileHandle:=FileCreate(SaveFilePath+'test1.req');
if iFileHandle > 0 then
begin
for i:=0 to Len-1 do
FileWrite(iFileHandle,packets[i],1);
FileClose(iFileHandle);
end else
ShowMessage('Create File '+SaveFilePath+'test.req Error!');
end else
ShowMessage('Create Dir Path '+SaveFilePath+' Error!');
end;
procedure TForm1.FormShow(Sender: TObject);
////初始化数据状态
begin
SetLength(packets,MAX_BUFFER);
lrcCheck:=0;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Len:=BuildPacket;
SaveToFile;
end;
procedure WriteLongToBuf(iTemp:integer;var packets:TBytes;var index:integer);
begin
TPInteger(integer(packets)+index)^:=iTemp;
inc(index,sizeof(integer));
end;
procedure WriteCharToBuf(cTemp:Char;var packets:TBytes;var index:integer);
begin
packets[index]:=Byte(cTemp);
inc(index);
end;
procedure WriteStringToBuf(strTemp:string;len:integer;var packets:TBytes;var index:integer);
begin
StrPLCopy(Pchar(integer(packets)+index),strTemp,len);
inc(index,len);
end;
function CalcuCheckValue(packets:TBytes;iPos,lrcCheck:integer):integer;
var
i:integer;
begin
for i:=1 to iPos-1 do /////不与STX校验,故下标从1开始。
begin
lrcCheck:=packets[i] XOR lrcCheck;
end;
Result:=lrcCheck;
end;
end.
Top
9 楼yxjjx(孤行者)回复于 2001-09-30 16:31:45 得分 0
帮你upTop
10 楼gzmhero(hihihi)回复于 2001-10-08 20:27:07 得分 200
兄弟,帮你写了这么多代码,好不好用,给个话啊。Top




