📄 复件 comm.c
字号:
#include<stdio.h>
#include<dos.h>
#include<conio.h>
#define O_TEXT 0x4000
#define O_BINARY 0x8000
#define SIZE 1024*16 /*定义接收缓冲区大小*/
#define PTL 0x01 /*波特率*/
unsigned char state;
void init_COM_INT(); /*初始化COM2端口,用于中断*/
void init_COM_C(); /*初始化COM2端口,用于查询方式*/
void send_w();/*发送等待*/
void receive_w(); /*接收等待*/
long file_size(FILE *fp);/*计算文件大小*/
void send_ch();/*发送字符,字符串*/
void send_file();/*发送字符,字符串*/
void receive_file();/*接收文件*/
void interrupt (*old_int)(void);
void interrupt far receive_intr();/*中断服务程序,用于中断接收文件*/
void file_begin();
int flag=1;
void init_COM_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_COM_INT()
{
outportb(0x2FB,0x80); /*设置波特率*/
outportb(0x2F8,PTL);
outportb(0x2F9,0x00);
outportb(0x2FB,0x0b);
outportb(0x2FC,0x0b); /*打开中断开关out2,这样8250产生的中断信号可以通过系统总线送给8259中断控制器*/
outportb(0x2F9,0x01); /*允许接收中断*/
}
void send_w()/*发送等待,检测发送寄存器*/
{
state=inportb(0x2FD); /*2FD为线路状态寄存器*/
state=state&0x20; /*判断发送寄存器是否为空*/
while(!state)
{
state=inportb(0x2FD); /*循环检测,当state&0x20为1时表示可以发送数据*/
state=state&0x20;
}
}
void close_intr()/*关闭中断*/
{
unsigned char i;
disable(); /*关闭中断*/
outportb(0x2F9,0x00); /*恢复原来状态,不允许接收中断*/
outportb(0x2FC,0x03); /*设置MODEM控制寄存器,恢复原来状态*/
i=inportb(0x21);
i=i|0x10; /*8259复位原先的IR4的状态*/
outportb(0x21,i);
enable(); /*开中断*/
setvect(0x0c,old_int); /*恢复原来的中断向量*/
}
void receive_w() /*接收等待,检测接受寄存器*/
{
state=inportb(0x2FD); /*2FD为线路状态寄存器*/
state=state&0x01; /*判断接受数据是否准备好*/
while(!state)
{
state=inportb(0x2FD);
state=state&0x01;
}
}
void send_ch() /*发送字符,字符串*/
{
unsigned char ch;
printf("\1 Please input the strings you want to send:");
L:
send_w(); /*发送之前查询发送寄存器是否为空*/
ch=getch();
printf("%c",ch);
if(ch!=13) /*输入字符不是回车时继续发送*/
{
outportb(0x2F8,ch); /*发送字符到接收寄存器*/
goto L;
}
else printf("\n\n\t\tSend have completed!\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 send_file()
{
FILE *fp;
char buf[SIZE]; /*缓存*/
char ch;
long yiwei[4]; /*用来存放文件大小的4个字节*/
long count;
char filename[20]; /*文件名*/
long file_len; /*文件大小*/
long size,sizey=0;/*还没有发送的文件长度*/
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); /*获得文件长度*/
send_w(); /*发送等待*/
printf("\t\tfile_len= %3.2f kb\n",file_len*1.0/1024);
outportb(0x2F8,'@'); /*发送开始字符,发送文件开始的握手信号*/
/* 首先 发送文件长度*/
yiwei[0]=file_len>>24;
yiwei[1]=file_len<<8; /*通过移位把32位的数据截成4个8位数据,发送文件长度大小给接收方*/
yiwei[1]=yiwei[1]>>24;
yiwei[2]=file_len<<16;
yiwei[2]=yiwei[2]>>24;
yiwei[3]=file_len<<24;
yiwei[3]=yiwei[3]>>24;
send_w(); /* 发送等待*/
for( i=0;i<4;i++)
{
send_w();
outportb(0x2F8,yiwei[i]); /*发送文件的大小*/
}
/* 发送文件长度结束 */
receive_w(); /*接收等待*/
state=inportb(0x2F8);
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++)
{
send_w();
outportb(0x2F8,buf[i]); /*发送文件*/
}
size-=SIZE; /*文件大小减少16k*/
printf("size=%d",size);
send_w();
outportb(0x2F8,'?'); /*发送一个标志'?'用于检查接收方是否已经接收完16k字节*/
receive_w(); /*接收等待*/
ch=inportb(0x2F8);
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++)
{
send_w();
outportb(0x2F8,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 receive_ch() /*接收字符*/
{
unsigned char ch;
printf("\t\t\nThe strings that receive are:");
do{
do{
state=inportb(0x2Fd)&0x01; /*判断接收数据是否准备好*/
}while(state!=0x01);
ch=inportb(0x2F8); /*接收数据*/
printf("%c",ch);
}while(ch!='\n');
printf("\n\t\tReceive strings complete! \n");
}
void receive_file()/*接收文件*/
{
unsigned char i;
int j=0;
FILE *fp;
char buf[SIZE]; /*缓存*/
char ch;
char filepath[20]; /*文件的存放路径*/
long file=0;
long size;
long sizey=0;
long len[4];/*用来接收发送方传过来的文件大小*/
float file1;
printf("\n\t\tReceive the size of the file !\n");
for(j=0;j<4;j++)
{
receive_w();
len[j]=inportb(0x2F8); /*接收文件的大小*/
}
len[0]= len[0]<<24;
len[1]= len[1]<<16;
len[2]= len[2]<<8;
size= len[0]|len[1]|len[2]|len[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(0x2F8,'n'); /*如果创建文件失败就发送一个字符'n'给发送方*/
return;
}
else
{
send_w();
outportb(0x2F8,'y'); /*如果创建文件成功就发送一个字符'y'给发送方*/
}
printf("\n\t\tBegin to receive the file \n");
while(size>SIZE) /*循环接收16k字节*/
{
for(j=0;j<SIZE;j++)
{
receive_w();
buf[j]=inportb(0x2F8); /*接收文件数据*/
}
receive_w();
/*i = inportb(0x2F8); */
/*printf("i=%c",i); */
if(inportb(0x2F8)=='?') /*当接收到一个标志'?'时,表示已经接收完16k字节*/
{
fwrite(buf,j,1,fp); /*把接收的数据写到文件中*/
size-=SIZE;
send_w(); /*发送等待*/
outportb(0x2F8,'!'); /*发送一个标志'!'用于答复发送方已经把16k数据写入了文件中*/
}
else
{
send_w();
outportb(0x2F8,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++)
{
receive_w();
buf[j]=inportb(0x2F8); /*接收完剩下的不到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 completely! the total size you have received is %3.2f Kb\n",file1);
fclose(fp);
return;
}
void interrupt far receive_intr(void) /*中断服务程序用于接收文件*/
{
receive_w(); /*接收等待*/
state=inportb(0x2F8);
/*printf("%c",state);*/
if(state=='@') /*当接收到发送文件开始的握手信号时,开始接收*/
{
flag=0;
receive_file();
}
else printf("\n\t\t Error!\n");
/*int flag=0; */
close_intr(); /*关闭中断*/
printf("\n");
outportb(0x20,0x20);
}
void file_begin()
{
init_COM_INT();
old_int = getvect(0x0b); /*获8259 RQ4中断类型*/
disable(); /*初始化中断系统时,应该关闭中断,初始化完成后再开放*/
state=inportb(0x21); /*0021H为8259口地址2,用来写ICW2、ICW4*/
state=state&0xe7; /*开8259 RQ4中断11101111*/
outportb(0x21,state); /*写OWC1使中断RQ4开放*/
setvect(0x0b,receive_intr); /*置中断向量类型asyncint*/
enable();
while(flag){ } /*初始化完成后再开放中断*/
}
void main()
{
char c,d;
printf("\n");
printf(" \1 Communication between two computer \1 \n");
printf("\t\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3\n\n");
printf("\t\t\t\t\1 1.Send strings \n\n");
printf("\t\t\t\t\1 2.Receive strings \n\n");
printf("\t\t\t\t\1 3.Send file \n\n");
printf("\t\t\t\t\1 4.Receive file \n\n");
printf("\t\t\t\t\1 5.Exit \n\n");
printf("\t\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3==\3\n\n");
printf("\n\n\t\t\Please choose :");
c=getchar();
d=getchar();
switch(c)
{
case '1':
clrscr();
printf("\t\t\t\t1.SEND STRINGS\n\n");
init_COM_C();
send_ch();
break;
case '2':
clrscr();
printf("\t\t\t\t2.RECEIVE STRINGS\n\n");
init_COM_C();
receive_ch();
break;
case '3':
clrscr();
printf("\t\t\t\t3.SEND FILE\n\n");
init_COM_C();
send_file();
break;
case '4':
clrscr();
printf("\t\t\t\t4.RECEIVE FILE\n");
init_COM_INT();
file_begin();
break;
}
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -