Тексты программ Ниже приведен текст файла-заголовка, который используется как 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() { }