?? lyb.c
字號:
#include<stdio.h>
#include<dos.h>
#include<conio.h>
#define SIZE 1024*16 /*定義接收緩沖區大小*/
int PTL; /*波特率*/
unsigned char state;
void init_COM1_INT(); /*初始化COM1端口,用于中斷*/
void init_COM1_C(); /*初始化COM1端口,用于查詢方式*/
void send1_w();/*發送等待*/
void receive1_w(); /*接收等待*/
void init_COM2_INT(); /*初始化COM2端口,用于中斷*/
void init_COM2_C(); /*初始化COM2端口,用于查詢方式*/
void send2_w();/*發送等待*/
void receive2_w(); /*接收等待*/
long file_size(FILE *fp);/*計算文件大小*/
void send1_ch();/*發送字符,字符串*/
void send1_file();/*發送文件*/
void receive1_ch();
void receive1_file();/*接收文件*/
void close1_intr();
void send2_ch();/*發送字符,字符串*/
void send2_file();/*發送文件*/
void receive2_ch();
void receive2_file();/*接收文件*/
void close2_intr();
void interrupt (*old_int)(void);
void interrupt far receive1_intr();/*中斷服務程序,用于中斷接收文件*/
void file1_begin();
void interrupt far receive2_intr();/*中斷服務程序,用于中斷接收文件*/
void file2_begin();
int flag=1;
int r;
void drawwindow()
{
clrscr();
textbackground(2);//選擇文本背景顏色
clrscr();
}
void init_COM1_C() /*初始化COM1端口*/
{
outportb(0x3FB,0x80); /*最高位置為1設置波特率*/
outportb(0x3F8,PTL); /*除數的低8位*/
outportb(0x3F9,0x00); /*除數的高8位*/
outportb(0x3FB,0x0b); /*3FB是通信線路控制寄存器,設置8數據位,一個停止位*/
outportb(0x3FC,0x03); /*設置3FC端口MODEM控制寄存器,使8250輸出DTR(數據終端準備好)和RTS(請求發送)*/
outportb(0x3F9,0x00); /*關閉所有中斷*/
}
void init_COM1_INT()
{
outportb(0x3FB,0x80); /*設置波特率*/
outportb(0x3F8,PTL);
outportb(0x3F9,0x00);
outportb(0x3FB,0x0b);
outportb(0x3FC,0x0b); /*打開中斷開關out2,這樣8250產生的中斷信號可以通過系統總線送給8259中斷控制器*/
outportb(0x3F9,0x01); /*允許接收中斷*/
}
void send1_w()/*發送等待,檢測發送寄存器*/
{
state=inportb(0x3FD); /*3FD為線路狀態寄存器*/
state=state&0x20; /*判斷發送寄存器是否為空*/
while(!state)
{
state=inportb(0x3FD); /*循環檢測,當state&0x20為1時表示可以發送數據*/
state=state&0x20;
}
}
void close1_intr()/*關閉中斷*/
{
unsigned char i;
disable(); /*關閉中斷*/
outportb(0x3F9,0x00); /*恢復原來狀態,不允許接收中斷*/
outportb(0x3FC,0x03); /*設置MODEM控制寄存器,恢復原來狀態*/
i=inportb(0x21);
i=i|0x10; /*8259復位原先的IR4的狀態*/
outportb(0x21,i);
enable(); /*開中斷*/
setvect(0x0c,old_int); /*恢復原來的中斷向量*/
}
void receive1_w() /*接收等待,檢測接受寄存器*/
{
state=inportb(0x3FD); /*3FD為線路狀態寄存器*/
state=state&0x01; /*判斷接受數據是否準備好*/
while(!state)
{
state=inportb(0x3FD);
state=state&0x01;
}
}
void send1_ch() /*發送字符,字符串*/
{
unsigned char ch;
printf("\1 Please input the strings you want to send:");
L:
send1_w(); /*發送之前查詢發送寄存器是否為空*/
ch=getch();
printf("%c",ch);
if(ch!=13) /*輸入字符不是回車時繼續發送*/
{
outportb(0x3F8,ch); /*發送字符到接收寄存器*/
goto L;
}
else printf("\n\n\t\t Sending finish!\n");
}
long file_size(FILE *fp)/*計算文件大小*/
{
long file_len;
fseek(fp,0,SEEK_END);/*在文件指針中定位*/
file_len=ftell(fp);
fseek(fp,0,SEEK_SET);
return file_len; /*返回文件大小*/
}
void send1_file()
{
FILE *fp;
char buf[SIZE]; /*緩存*/
char ch;
long len1[4]; /*用來存放文件大小的4個字節*/
long count;
char filename[20]; /*文件名*/
long file_len; /*文件大小*/
long size;/*還沒有發送的文件長度*/
int i=0;
long file=0;
double time,time1; /*用于計算發送時間*/
double time2;
double speed; /*用于計算發送速度*/
double baifen;
float file1;
printf("\nPlease input the name of the file that you want to send:");
scanf("%s",filename);
if((fp=fopen(filename,"rb+"))==NULL)/*以二進制方式打開文件*/
{
printf("\t\tCann't open the file! \n");
return;
}
file_len=file_size(fp); /*獲得文件長度*/
send1_w(); /*發送等待*/
printf("\t\tfile_len= %3.2f kb\n",file_len*1.0/1024);
outportb(0x3F8,'@'); /*發送開始字符,發送文件開始的握手信號*/
/* 首先 發送文件長度*/
len1[0]=file_len>>24;
len1[1]=file_len<<8; /*通過移位把32位的數據截成4個8位數據,發送文件長度大小給接收方*/
len1[1]=len1[1]>>24;
len1[2]=file_len<<16;
len1[2]=len1[2]>>24;
len1[3]=file_len<<24;
len1[3]=len1[3]>>24;
send1_w(); /* 發送等待*/
for( i=0;i<4;i++)
{
send1_w();
outportb(0x3F8,len1[i]); /*發送文件的大小*/
}
/* 發送文件長度結束 */
receive1_w(); /*接收等待*/
state=inportb(0x3F8);
if(state!='y') /*如果接方創建文件失敗,則返回一個信息給發送方*/
{
printf("\t\tCreat file fail,please try again!\n");
return;
}
else
{
printf("\t\tthe Receiver has created the sending file successfully !\n");
printf("\t\tbeginning to send the file....\n");
}
i=0;
size = file_len;
time=(double)clock(); /*計算開始發送的時間*/
while(size>SIZE) /* begin 發送文件,每發16k字節發一個字母當校驗用*/
{
fread(buf,SIZE,1,fp); /*把文件的16k字節讀到緩存*/
for(i=0;i<SIZE;i++)
{
send1_w();
outportb(0x3F8,buf[i]); /*發送文件*/
}
size-=SIZE; /*文件大小減少16k*/
printf("size=%d",size);
send1_w();
outportb(0x3F8,'?'); /*發送一個標志'?'用于檢查接收方是否已經接收完16k字節*/
receive1_w(); /*接收等待*/
ch=inportb(0x3F8);
if(ch!='!') /*如果對方發送回來提示效檢字節錯,則重發16k字節*/
{
fseek(fp,SIZE,SEEK_CUR);/*文件指針前移16k字節*/
size+=SIZE;
}
printf("%c\n",ch);
file=file+SIZE;
clrscr();
printf("\t\tYou have already sent %3.2f(kb),and left %3.2f(kb)\n",file * 1.0 / 1024,size * 1.0 / 1024);
}
if(size>0)
{
fread(buf,size,1,fp);
for(i=0;i<size;i++)
{
send1_w();
outportb(0x3F8,buf[i]); /*把剩余的不到16k的字節發送完*/
}
}
file=file+size;
size-=size;
time1=(double)clock(); /*得到發送結束后的時間*/
time2=(time1-time)/18.2; /*計算總共用去的時間*/
/*speed=file/time2; 計算傳輸速度*/
file1=(float)(file/(1024));
speed=file1/time2; /*計算傳輸速度*/
printf("\n\t\tFile had sent already! the size of the file are %3.2fK\n",file1);
printf("\n\t\tThe sending speed is :%3.2f(kb/s)",speed);
fclose(fp);/*關閉文件*/
}
void receive1_ch() /*接收字符*/
{
unsigned char ch;
printf("\t\t\nThe strings that receive are:");
do{
do{
state=inportb(0x3Fd)&0x01; /*判斷接收數據是否準備好*/
}while(state!=0x01);
ch=inportb(0x3F8); /*接收數據*/
printf("%c",ch);
}while(ch!='\n');
printf("\n\t\tReceive finish! \n");
}
void receive1_file()/*接收文件*/
{
unsigned char i;
int j=0;
FILE *fp;
char buf[SIZE]; /*緩存*/
char ch;
char filepath[20]; /*文件的存放路徑*/
long file=0;
long size;
long len2[4];/*用來接收發送方傳過來的文件大小*/
float file1;
printf("\n\t\tReceive the size of the file !\n");
for(j=0;j<4;j++)
{
receive1_w();
len2[j]=inportb(0x3F8); /*接收文件的大小*/
}
len2[0]= len2[0]<<24;
len2[1]= len2[1]<<16;
len2[2]= len2[2]<<8;
size= len2[0]|len2[1]|len2[2]|len2[3]; /*計算文件的大小*/
printf("\t\tThe receiving file's size is:%3.2f kb\n",size * 1.0 / 1024);
printf("\n\n\tPlease input the saving path of the file:");
scanf("%s",filepath);
if((fp=fopen(filepath,"wb"))==NULL)
{
printf("\n\t\tCann't open the file %s!",filepath);
outportb(0x3F8,'n'); /*如果創建文件失敗就發送一個字符'n'給發送方*/
return;
}
else
{
send1_w();
outportb(0x3F8,'y'); /*如果創建文件成功就發送一個字符'y'給發送方*/
}
printf("\n\t\tBegin to receive the file \n");
while(size>SIZE) /*循環接收16k字節*/
{
for(j=0;j<SIZE;j++)
{
receive1_w();
buf[j]=inportb(0x3F8); /*接收文件數據*/
}
receive1_w();
/*i = inportb(0x3F8); */
/*printf("i=%c",i); */
if(inportb(0x3F8)=='?') /*當接收到一個標志'?'時,表示已經接收完16k字節*/
{
fwrite(buf,j,1,fp); /*把接收的數據寫到文件中*/
size-=SIZE;
send1_w(); /*發送等待*/
outportb(0x3F8,'!'); /*發送一個標志'!'用于答復發送方已經把16k數據寫入了文件中*/
}
else
{
send1_w();
outportb(0x3F8,0x00); /*當沒有接收到一個標志'?'時,表示需要重發剛才的16k字節*/
}
file=file+SIZE;
clrscr();
printf("\t\tYou have already received %3.2f(kb),and left %3.2f(kb)\n",file * 1.0/1024,size * 1.0 /1024);
}
if(size>0)
{
for(j=0;j<size;j++)
{
receive1_w();
buf[j]=inportb(0x3F8); /*接收完剩下的不到16k的字節*/
}
fwrite(buf,j,1,fp); /*寫到文件中*/
}
file=file+size;
size-=size;
file1=(float)(file/(1024));
printf("\n\t\tYou have already received %3.2f(kb),and left %3.2f(kb)\n",file *1.0/1024,size *1.0/1024);
printf("\n\n\t\tReceive finish! the total size you have received is %3.2f Kb\n",file1);
fclose(fp);
return;
}
void interrupt far receive1_intr(void) /*中斷服務程序用于接收文件*/
{
receive1_w(); /*接收等待*/
state=inportb(0x3F8);
/*printf("%c",state);*/
if(state=='@') /*當接收到發送文件開始的握手信號時,開始接收*/
{
flag=0;
receive1_file();
}
else printf("\n\t\t Error!\n");
/*int flag=0; */
close1_intr(); /*關閉中斷*/
printf("\n");
outportb(0x20,0x20);
}
void file1_begin()
{
init_COM1_INT();
old_int = getvect(0x0c); /*獲8259 RQ4中斷類型*/
disable(); /*初始化中斷系統時,應該關閉中斷,初始化完成后再開放*/
state=inportb(0x21); /*0021H為8259口地址2,用來寫ICW2、ICW4*/
state=state&0xe7; /*開8259 RQ4中斷11101111*/
outportb(0x21,state); /*寫OWC1使中斷RQ4開放*/
setvect(0x0c,receive1_intr); /*置中斷向量類型asyncint*/
enable();
while(flag){ } /*初始化完成后再開放中斷*/
}
void init_COM2_C() /*初始化COM2端口*/
{
outportb(0x2FB,0x80); /*最高位置為1設置波特率*/
outportb(0x2F8,PTL); /*除數的低8位*/
outportb(0x2F9,0x00); /*除數的高8位*/
outportb(0x2FB,0x0b); /*2FB是通信線路控制寄存器,設置8數據位,一個停止位*/
outportb(0x2FC,0x03); /*設置2FC端口MODEM控制寄存器,使8250輸出DTR(數據終端準備好)和RTS(請求發送)*/
outportb(0x2F9,0x00); /*關閉所有中斷*/
}
void init_COM2_INT()
{
outportb(0x2FB,0x80); /*設置波特率*/
outportb(0x2F8,PTL);
outportb(0x2F9,0x00);
outportb(0x2FB,0x0b);
outportb(0x2FC,0x0b); /*打開中斷開關out2,這樣8250產生的中斷信號可以通過系統總線送給8259中斷控制器*/
outportb(0x2F9,0x01); /*允許接收中斷*/
}
void send2_w()/*發送等待,檢測發送寄存器*/
{
state=inportb(0x2FD); /*2FD為線路狀態寄存器*/
state=state&0x20; /*判斷發送寄存器是否為空*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -