LINUX.ORG.RU
решено ФорумTalks

Читаю «Сети» дальше...

 , ,


1

1

Итак, простой вопрос:

Посмотрите на пример с файловым сервером, приведенный в листинге 6.1.Может ли системный вызов клиента connect() закончиться неудачно по причине, отличной от переполнения очереди ожидания сервера? Считайте, что сеть идеальна.

/* На этой странице содержится клиентская программа, запрашивающая файл у серверной
   программы, расположенной на следующей странице. */
/* Сервер в ответ на запрос высылает файл.*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include<sys/types.h>
#define SERVER_PORT 987 /* По договоренности между клиентом и сервером */
#define BUF_SIZE 4096 /* Размер передаваемых блоков */
int main(int argc, char *argv)
{
  int c,s,bytes;
  char buf[BUF_SIZE];
  /*буфер для входящего файла */
  struct hostent *h;
  /*информация о сервере */
  struct sockaddr_in channel; /*хранит IP=адрес */
  if (argc!=3) fatal("Для запуска введите: client имя_сервера имя_файла");
  h = gethostbyname(argv[1]);
  /* поиск IP-адреса хоста */
  if(!h) fatal("Ошибка выполнения gethostbyname");
  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (s<0) fatal("Сокет");
  memset(&channel, 0, sizeof(channel));
  channel.sin_family=AF_INET;
  memcpy(&channel.sin_addr.s_addr,h ->h_addr,h ->h_length);
  channel.sin_port=htons(SERVER_PORT);
  c = connect(s,(struct sockaddr *) &channel, sizeof(channel));
  if (c<0) fatal("Ошибка соединения");
  /* Соединение установлено. Посылается имя файла с нулевым байтом на конце */
  write (s, argv[2], strlen(argv[2])+1);
  /* Получить файл, записать на стандартное
     устройство вывода */
  while (1) {
    bytes = read(s, buf, BUF_SIZE); /*
				      Читать из сокета */
    if (bytes <= 0) exit(0);
    /*
      Проверка конца файла */
    write(1, buf, bytes);
    /*
      Записать на стандартное устройство вывода */
  }
}
fatal(char *string)
{
  printf("%s\n", string);
  exit(1);
}
Как я понимаю, здесь не проверяется длина имени хоста и/или формат и длина IP-адреса, вследствии этого возможно передав некорректный параметр затереть следующее поле структуры.

Так или нет?

★★★★★

Последнее исправление: Twissel (всего исправлений: 3)

Разумеется, может. Любая сетевая ошибка, которые сотни - неверный адрес сервера, ошибка DNS, ошибка связи...

Как я понимаю, здесь не проверяется длина имени хоста и/или формат и длина IP-адреса

connect ничего не проверят, но он завершится ошбкой, если что-то не так. Не сможет соединиться по естественным причинам.

lenin386 ★★★★
()
Последнее исправление: lenin386 (всего исправлений: 3)

Запустите emacs, вставьте этот код. Выделите вставленный текст кода целиком. Наберите командную комбинацию клавиш M-x (Alt-x). Введите indent-region и нажмите Enter.

Само отформатирует код!

nerdogeek
()
Ответ на: комментарий от nerdogeek

Реквестирую ту же последовательность действий только для vim. emacs сегодня ставить не охота ;)

Twissel ★★★★★
() автор топика
Ответ на: комментарий от nerdogeek

Вроде сделал как Вы просили, так лучше?

Twissel ★★★★★
() автор топика

не проверяется длина имени хоста и/или формат и длина IP-адреса

Длину имени хоста здесь проверять не нужно, это внутренняя задача gethostbyname. Длину (а точнее тип) адреса проверять нужно, ибо если gethostbyname вернет IPv6 адрес, то последующий memcpy выйдет за пределы структуры sockaddr_in, выделенной на стеке.

Deleted
()
Ответ на: комментарий от nerdogeek

Запустите emacs, вставьте этот код. Выделите вставленный текст кода целиком. Наберите командную комбинацию клавиш M-x (Alt-x). Введите indent-region и нажмите Enter.

Само отформатирует код!

Похоже на работу оператора телетайпа.

21 век как бэ, нормальные редакторы должны сами подсвечивать код при вставке.

Igron ★★★★★
()
Ответ на: editor-agnostic от theNamelessOne

ОК, зайду на неделе, гляну.

Twissel ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.