[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Тексты программ

Ниже приведен текст файла-заголовка, который используется как xmit.c,
так и recv.c.
xmit.h:

  1 #define   DATASIZE    124
  2 #define   BLOCKSIZE   (DATASIZE+4)   /* size of data block */
  3
  4 #define   HEXTABLE    "0123456789ABCDEF"
  5 #define   HEXTABSIZ   (sizeof(HEXTABLE)-1)
  6
  7 void putbyte(char *, int);
  8 void transmit(int fd);
  9 void setrawio(int);
 10 void putrawio(int);
 11 void setrawio(int);
 12 void restorio(int);
 13 int receive(int);
 14 int getbyte(char *);

Эта программа собирает 128-символьные блоки, которые пишутся в
стандартный вывод. Последние четыре символа содержат количество
символов данных в блоке и контрольную сумму блока. Сумма образуется
путем сложения размера блока и суммы всех значений байтов данных.
Передается только восемь младших бит суммы. Конец файла обозначается
блоком нулевой длины.
xmit.c:

  1 /*
  2  * transmit a file
  3  *
  4  *      usage: xmit filename
  5  */
  6
  7 #include <unistd.h>
  8 #include <stdlib.h>
  9 #include <stdio.h>
 10 #include <fcntl.h>
 11 #include "xmit.h"
 12
 13 main(int argc, char *argv[])
 14 {
 15     int fd;
 16
 17     if (argc < 2) {
 18         fprintf(stderr, "Usage: %s filename\n", argv[0]);
 19         exit(1);
 20     }
 21     if ((fd = open(argv[1], O_RDONLY)) == -1) {
 22         perror(argv[1]);
 23         exit(2);
 24     }
 25     setrawio(1);
 26     transmit(fd);
 27     restorio(1);
 28     close(fd);
 29     exit(0);
 30 }
 31
 32
 33 void transmit(int fd)   /* transmit a file */
 34 {
 35     int size;
 36     int checksum, i;
 37     char block[BLOCKSIZE];
 38
 39     while ((size = read(fd, block, DATASIZE)) > 0) {
 40         checksum = size;
 41         for (i = 0; i < size; i++)
 42             checksum += block[i];
 43         putbyte(block+DATASIZE, size);
 44         putbyte(block+DATASIZE+2, (checksum & 0xff));
 45         write(1, block, BLOCKSIZE);
 46     }
 47     putbyte(block+DATASIZE, 0);     /* end-of-file */
 48     write(1, block, BLOCKSIZE);
 49 }
 50
 51
 52 void putbyte(char *str, int n) /*convert byte value to two hex
 53 {
 54     static char hex[ ] = HEXTABLE;
 55     *str++ = hex[(n & 0xff) >> 4];
 56     *str = hex[n & 0x0f];
 57 }

Эта программа получает восьмибитные данные блоками по 128 символов.
Перед каждым чтением из стандартного ввода устанавливается будильник
на десять секунд. Эта программа завершается с сообщением об ошибке,
если в течении десяти секунд не было получено никакого ввода. Кроме
того, она подсчитывает количество ошибок контрольной суммы. Сумма
вычисляется так же, как в xmit, и сравнивается с полученным значением.
Эти две программы проверялись путем передачи/приема данных между
различными системами различных изготовителей.
recv.c:

  1 /*
  2  * receive a file
  3  *
  4  *      usage: recv filename
  5  */
  6 #include <unistd.h>
  7 #include <stdlib.h>
  8 #include <stdio.h>
  9 #include <fcntl.h>
 10 #include <signal.h>
 11 #include "xmit.h"
 12 static void sigcatch();
 13
 14 int checkerrs;          /* number of checksum errors */
 15
 16 main(int argc, char *argv[])
 17 {
 18     int fd, retcode;
 19
 20     if (argc < 2) {
 21         fprintf(stderr, "Usage: %s filename\n", argv[0]);
 22         exit(1);
 23     }
 24     if ((fd = open(argv[1], O_WRONLY | O_CREAT |
 25         O_TRUNC, 0666)) == -1) {
 26         perror(argv[1]);
 27         exit(3);
 28     }
 29     setrawio(0);
 30     retcode = receive(fd);
 31     restorio(0);
 32     close(fd);
 33     if (retcode == -1) {
 34         fprintf(stderr, "Timed out!\n");
 35         exit(4);
 36     }
 37     if (checkerrs > 0) {
 38         fprintf(stderr, "%d Checksum errors\n",
 39             checkerrs);
 40         exit(5);
 41     }
 42     exit(0);
 43 }
 44
 45
 46 int receive(int fd)     /* receive file */
 47 {
 48     int size, checksum;
 49     int  i, n, trialsum;
 50     char block[BLOCKSIZE];  /* data block */
 51
 52     sigset(SIGALRM, sigcatch);
 53     alarm(10);
 54     while ((n = read(0, block, BLOCKSIZE)) > 0) {
 55         size = getbyte(block+DATASIZE);
 56         if (size == 0)          /* end-of-file */
 57             break;
 58         if (size > BLOCKSIZE)
 59             size = BLOCKSIZE;
 60         trialsum = size;
 61         for (i = 0; i < size; i++)
 62             trialsum += block[i];
 63         checksum = getbyte(block+DATASIZE+2);
 64         if (checksum != (trialsum & 0xff))
 65             checkerrs++;    /* checksum error */
 66         write(fd, block, size);
 67         alarm(10);
 68     }
 69     alarm(0);
 70     if (n == -1)
 71         return(-1);
 72     return(0);
 73 }
 74
 75
 76 int getbyte(char *str)  /*compute byte value from two hex chars
 77 {
 78     static char hex[ ] = HEXTABLE;
 79     int i, j, k, n = 0;
 80
 81     for (i = 0; i < 2; i++) {
 82         for (j = 0; j < HEXTABSIZ; j++)
 83             if (str[i] == hex[j])
 84                 k = j;
 85         n = n * HEXTABSIZ + k;
 86     }
 87     return(n);
 88 }
 89
 90
 91 static void sigcatch() { }