📄 源程序清单.c
字号:
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <stdlib.h>
#include <bios.h>
#include <string.h>
#define SIZE 32768
void InitData(void); /*端口初始化*/
void Initscreen(void); /*屏幕初始化*/
void Send(void); /*发送字符*/
void SandRchar(void); /*发送并接收字符*/
void Sdfile(void); /*发送文件函数*/
void Receive(void); /*接收字符函数*/
void Rcfile(void); /*接收文件函数*/
void recv_wait(); /*接收等待函数*/
void send_wait(); /*发送等待函数*/
void interrupt far char_proc(void); /*中断函数*/
void interrupt ( *mode)(void); /*中断向量*/
char filename[20];
int com1;
int flag=1;
long ii;
unsigned char state; /*定义几个全局变量*/
typedef struct
{
char *base;
int front;
int rear;
} /*定义队列*/
SqQueue;
int InitQueue(SqQueue *Q) /*构造一个空队列Q*/
{
Q->base=(char *) malloc(SIZE+1 *sizeof(char));
if(!Q->base) exit(-2);
Q->front=Q->rear=0;
return 1;
}
int QueueLength(SqQueue *Q) /*返回Q的元素个数,即队列的长度*/
{
return (Q->rear-Q->front+SIZE)%SIZE;
}
int EnQueue(SqQueue *Q,char e)/*插入元素e为Q的新的队尾元素*/
{
if((Q->rear+1)%SIZE==Q->front) return 0;
Q->base[Q->rear]=e;
Q->rear=(Q->rear+1)%SIZE;
return 1;
}
int DeQueue(SqQueue *Q ,char *e)/*若队列不空,则删除Q的队头元素,用e返回其值,并返回1;否则返回0 */
{
if(Q->front==Q->rear) return 0;
*e=Q->base[Q->front];
Q->front=(Q->front+1)%SIZE;
return 1;
}
void CrQueue(SqQueue *Q)/*清空队列*/
{
Q->front=Q->rear=0;
}
union
{
char c[sizeof(long)];
long len;
}
scnt,rcnt; /*用联合体表示文件的长度*/
SqQueue Q; /*创建一个全局的队列变量*/
/************初始化com1端口************/
void InitData()
{
unsigned char i,j;
com1=0x3f8;
InitQueue(&Q); /*初始化队列*/
j=inportb(com1+3); /*取线路控制寄存器的值*/
j=j|0x80; /*使DLAB=1,对除数寄存器置初值*/
outportb(com1+3,j);
outportb(com1,0x01);/*写除数寄存器低八位*/
outportb(com1+1,0); /*写除数寄存器高八位*/
j=inportb(com1+3);
j=j&0x7f; /*使DLAB=0*/
outportb(com1+3,j);
outportb(com1+3,0x03);
}
/************发送字符************/
void Send()
{
unsigned char at;
char c;
at=inportb(com1+5);
at=at&0x20;
if(at) if(DeQueue(&Q,&c)) outportb(com1,c);
}
/**************发送等待*************/
void send_wait()
{
state=inportb(com1+5);
state=state&0x20;
while(!state)
{
state=inportb(com1+5);
state=state&0x20;
}
}
/***********接收字符函数*************/
void Receive()
{
char c;
state=inportb(com1+5);
state=state&0x01;
if(state)
{
c=inportb(com1);
if(c=='\r')
printf("\n\n ");
else
{
textcolor(60);
cprintf("%c",c);
}
}
}
/**************接收等待****************/
void recv_wait()
{
state=inportb(com1+5);
state=state&0x01;
while(!state)
{
state=inportb(com1+5);
state=state&0x01;
}
}
/************发送或接收字符函数***************/
void SandRchar()
{
int i;
char c;
CrQueue(&Q);
clrscr();
printf("\n\n ------------------------------\n");
printf(" press ESC to be back \n");
printf(" ------------------------------\n\n");
printf("==================================================\n\n");
printf(" ");
while(1)
{
while(!kbhit()) /*没按键则一直发送,接收*/
{
Send();
Receive();
}
c=getch();
if(c=='\x1B') break; /*按ESC则退出*/
if(c=='\r') /*特殊处理回车键*/
{
printf("\n\n ");
EnQueue(&Q,c);
}
else
{ /*有按键就进队列,显示*/
EnQueue(&Q,c);
textcolor(10);
cprintf("%c",c);
}
}
}
/***************计算文件大小***************/
long get_file_size(FILE *temp_fp)
{
long temp_file_len;
fseek(temp_fp,0,SEEK_END); /*文件指针移到文件未尾*/
temp_file_len=ftell(temp_fp); /*文件指针未尾的位置,即文件长度*/
fseek(temp_fp,0,SEEK_SET); /*文件指针回到文件开头*/
return temp_file_len;
}
/***************发送文件***************/
void Sdfile()
{
FILE *fp;
unsigned char ch;
int i,done,j;
long t,t1;
float st;
unsigned long size;
done=j=0;
CrQueue(&Q);
while(done<4)
{
printf(" input file name you want to send: ");
scanf("%s",filename);
if((fp=fopen(filename,"rb"))==NULL)/*以二进制方式打开文件*/
{
printf("\n file open error! try again..... \n");
done++;
}
else done=5;
}
if(done==4)
{
printf("\n file open error too much time!\n");
getch();
return;
}
scnt.len=get_file_size(fp); /*获得文件长度*/
send_wait();
outportb(com1,'<'); /*发送开始字符*/
for(i=0;i<sizeof(long);i++) /*发送文件长度大小给接收方*/
{
send_wait();
outportb(com1,scnt.c[i]);
}
printf("\n\n Link.......wait...... \n");
recv_wait(); /*等待回应*/
state=inportb(com1);
if(state!='>')
{
printf("\n connect fail\n"); /*连接失败*/
return;
}
printf("\n connect succeed!\n");
size = scnt.len;
printf("\n The size of the file is %ld bytes;",size);
printf("\n\n Now Sending....... 00%");
t=clock();
/**********发送文件,每发4K字节发一个效验和字节*********/
while(size>SIZE)
{
for(ii=0;ii<SIZE;ii++)
{
ch=fgetc(fp);
EnQueue(&Q,ch);
Send();
}
while(QueueLength(&Q)) Send(); /*继续发队列中剩余的*/
size-=SIZE;
j++;
/***********发送效检和字节***********/
send_wait();
outportb(com1,'?');
recv_wait();
ch=inportb(com1);
if(ch!='!') /*if 对方发送回来提示效检字节错,则重发4K字节*/
{
fseek(fp,SIZE,SEEK_CUR);/*文件指针前移4K字节*/
size+=SIZE;
j--;
}
else {textcolor(10);cprintf("\b\b\b\b%3d%",100*j*SIZE/scnt.len);} /*显示发送进度*/
}
while(size>0) /*发送比4K小的字符*/
{
ch=fgetc(fp);
size--;
EnQueue(&Q,ch);
Send();
}
while(QueueLength(&Q)) Send();
t1=clock();
textcolor(60);
cprintf("\b\b\b\b100%");
fclose(fp); /*关闭文件*/
st=(t1-t)/18.2;
printf("\n\n Send Complete!\n\n");
printf(" Total use %5.3f s.\n\n",st);
printf(" Total send %ld Bytes.\n\n",scnt.len);
if(st>0) /*防止除数为0的情况*/
printf(" The rate is %5.3f Bytes/s.\n",scnt.len/st);
else printf(" The rate is 115.2 KBytes/s.\n");
getch();
}
/***********中断服务程序***********/
void interrupt far char_proc()
{
state=inportb(com1);
if(state=='<')
Rcfile();
flag=0;
outportb(0x20,0x20);
}
/***********初始化中断***********/
void init_pt()
{ char t;
mode = getvect(0x0c);/*获取中断处理程序的入口地址*/
disable(); /*关中断*/
outportb(0x3fc,0x08|0x0b); /*out2,dtr,rts信号有效*/
outportb(0x3f9,0x01); /*允许接收中断*/
t = inportb(0x21);
t = t&0xef; /* t & 1110 1111 ,开放IRQ4,即com1的中断请求*/
outportb(0x21,t);
setvect(0x0c,char_proc);
enable(); /*开中断*/
while(flag){}
outportb(0x3f9,0);
t = inportb(0x21);
t = t|0x10; /* t | 0001 0000 ,关IRQ4,即com1的中断请求*/
outportb(0x21,t);
setvect(0x0c,mode);/*为指定的中断向量设置中断服务函数,interruptno 中断向量,isr中断函数,该函数应使用interrupt关键字声明*/
flag=1;
}
/**************接收文件***************/
void Rcfile()
{
int done,i,j;
FILE *fp;
long sizec; /*文件的长度*/
unsigned char ch;
done=i=j=0;
CrQueue(&Q);
for(j=0;j<4;j++) /*接收文件长度*/
{
recv_wait();
rcnt.c[j]=inportb(com1);
}
sizec=rcnt.len;
while(!done)
{
printf("\n creat the file to receive and save : ");
scanf("%s",filename);
if((fp=fopen(filename,"wb"))==NULL)
{
printf(" file already exists !\n");
}
else done=1;
}
send_wait();
outportb(com1,'>');
printf("\n Now Receiving......... 00%"); /*接收进度条*/
while(rcnt.len>SIZE) /*每次接收4K*/
{
for(ii=0;ii<SIZE;ii++) /*接收4K,存入队列中*/
{
recv_wait();
ch=inportb(com1);
EnQueue(&Q,ch);
}
recv_wait();
state=inportb(com1);
if(state=='?') /*接收正确,把队列中的字符写入文件*/
{
for(ii=0;ii<SIZE;ii++)
{
DeQueue(&Q,&ch);
fputc(ch,fp);
}
rcnt.len-=SIZE; /*剩余的字节数*/
send_wait();
outportb(com1,'!'); /*回答发送方收接正确,继续发*/
i++;
textcolor(10);
cprintf("\b\b\b\b%3d%",100*i*SIZE/sizec); /*接收进度条*/
}
else
{
CrQueue(&Q); /*接收错误,清空队列重收*/
send_wait();
outportb(com1,0x00);
}
}
if(rcnt.len>0) /*接收剩余的字符*/
{
for(ii=0;ii<rcnt.len;ii++)
{
recv_wait();
ch=inportb(com1);
EnQueue(&Q,ch);
}
for(ii=0;ii<rcnt.len;ii++)
{
DeQueue(&Q,&ch);
fputc(ch,fp);
}
}
fclose(fp); /*关闭文件*/
textcolor(60);
cprintf("\b\b\b\b100%");
printf("\n\n Receive Complete!\n\n");
printf("\n\n Total send %ld Bytes.",sizec);
getch();
}
/*****************初始化屏幕*****************/
void Initscreen()
{
clrscr(); /*清屏*/
printf("\n");
printf("\n ------------------------------------------------");
printf("\n choice 1: send file; ");
printf("\n choice 2: receive file; ");
printf("\n choice 3: send receive char; ");
printf("\n choice 0: quit to window;");
printf("\n -------------------------------------------------\n");
}
/***************主函数*************/
main()
{
char ch;
InitData();
while(1)
{
Initscreen();
ch=getch();
while(ch!='1'&&ch!='2'&&ch!='3'&&ch!='0')
{
printf("\n ERROR! Please Choose Again\n\n");
ch=getch();
}
if(ch=='1') {printf("\n ------------SEND FILE PART------------ \n\n");
Sdfile();}
else if(ch=='2') {printf("\n ------------RECEIVE FILE PART------------ \n\n");
init_pt();}
else if(ch=='3') {printf("\n ------------TALKING PART------------- \n\n");
SandRchar();}
else if(ch=='0') exit(0);
else if(ch!='1'&&ch!='2'&&ch!='3'&&ch!='0')
ch=getch();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -