[<<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() { }