⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 复件 comm.c

📁 用C语言写的双机通信代码
💻 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 + -