55:  switch (errorCode) {

 56:  case FILE_NOT_FOUND:

 57:   strcpy(err.u.error.message, 'файл не найден');

 58:   break;

 59:  }

 60:

 61:  /* 2 байта кода операции, 2 байта кода ошибки, сообщение и '' */

 62:  size = 2 + 2 + strlen(err.u.error.message) + 1;

 63:  if (send(s, &err, size, 0) != size)

 64:   die('erarorsend');

 65: }

 66:

 67: void handleRequest(struct addrinfo tftpAddr,

 68:  struct sockaddr remote, int remoteLen,

 69:  struct tftpPacket request) {

 70:  char * fileName;

 71:  char * mode;

 72:  int fd;

 73:  int s;

 74:  int size;

 75:  int sizeRead;

 76:  struct tftpPacket data, response;

 77:  int blockNum = 0;

 78:

 79:  request.opcode = ntohs(request.opcode);

 80:  if (request.opcode != RRQ) die('неверный код операции');

 81:

 82:  fileName = request.u.bytes;

 83:  mode = fileName + strlen(fileName) + 1;

 84:

 85:  /* здесь поддерживается только режим bin */

 86:  if (strcmp(mode, 'octet')) {

 87:   fprintf(stderr, 'неверный режим %s ', mode);

 88:   exit(1);

 89:  }

 90:

 91:  /* требуется передача при помощи сокета того же семейства и типа,

 92:     с которым мы начинали */

 93:  if ((s = socket(tftpAddr.ai_family, tftpAddr.ai_socktype,

 94:   tftpAddr.ai_protocol)) < 0)

 95:   die('send socket');

 96:

 97:  /* установить удаленный конец сокета на адрес, который

 98:     инициирует данное соединение */

 99:  if (connect(s, &remote, remoteLen))

100:   die('connect');

101:

102:  if ((fd = open(fileName, O_RDONLY)) < 0) {

103:   sendError(s, FILE_NOT_FOUND);

104:   close(s);

105:   return;

106:  }

107:

108:  data.opcode = htons(DATA);

109:  while ((size = read(fd, data.u.data.bytes, 512)) > 0) {

110:   data.u.data.block = htons(++blockNum);

111:

112:   /* размер составляют 2 байта (код операции), 2 байта (номер блока) и данные*/

113:   size += 4;

114:   if (send(s, &data, size, 0) != size)

115:    die('data send');

116:

117:   sizeRead = recv(s, &response, sizeof(response), 0);

118:   if (sizeRead < 0) die('recv ack');

119:

120:   response.opcode = ntohs(response.opcode);

121:   if (response.opcode != ACK) {

122:    fprintf(stderr, 'непредвиденный код операции в отклике ');

123:    exit(1);

124:   }

125:

126:   response.u.ack.block = ntohs(response.u.ack.block);

127:   if (response.u.ack.block != blockNum) {

128:    fprintf(stderr, 'получено подтверждение неверного блока ');

129:    exit(1);

130:   }

131:

132:   /* если блок, который мы только что отправили, содержит

133:      меньше 512 байт, то задача выполнена */

134:   if (size < 516) break;

135:  }

136:

137:  close(s);

138: }

139:

140: int main(int argc, char ** argv) {

141:  struct addrinfo hints, * addr;

142:  char * portAddress = 'tftp';

143:  int s;

144:  int rc;

145:  int bytes, fromLen;

146:  struct sockaddr from;

147:  struct tftpPacket packet;

148:

149:  if (argc > 2) {

150:   fprintf(stderr, 'использование: tftpserver [порт] ');

151:   exit(1);

152:  }

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату