Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
      Languages 
      Kernels 
      Packages 
      Books 
      Tests 
      OS 
      Forum 
      Математика 
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Linux Kernel 2.6...2721 
 Rodriguez 3...2404 
 Сетунь...1538 
 FAQ...1500 
 M.Pilgrim->Часть 2...1492 
 M.Pilgrim->Часть 1...1490 
 C++ Patterns 3...1466 
 Clickhouse...1465 
 Trees...1457 
 William Gropp...1457 
 Стивенс 9...1456 
 Httpd-> История Ap...1453 
 Ethreal 4...1451 
 Part 3...1442 
 Ethreal 3...1440 
 Rodriguez 8...1440 
 Ext4 FS...1440 
 Rodriguez 7...1436 
 Максвелл 5...1434 
 Rodriguez 6...1433 
 
  01.01.2024 : 3621733 посещений 

iakovlev.org

 W. R. Stevens UNIX : Network Programming Networking APIs   Глава 1

 
 Глава 1
 
 Код для этой главы находится в архивном каталоге /intro .
 Рассматривается простой клиент-серверный сценарий :
 клиент устанавливает простое ТСР-соединение с сервером ,
 а сервер в ответ посылает текущее время .
 При чтении из сокета функцию read нужно вызывать циклически ,
 и прерывать функцию тогда , когда она возвращает 0 либо ошибку .
 
 Клиент :
 
 
 	int					sockfd, n;
 	char				recvline[MAXLINE + 1];
 	struct sockaddr_in	servaddr;
 
 	if (argc != 2)
 		err_quit("usage: a.out ");
 
 	if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
 		err_sys("socket error");
 
 	bzero(&servaddr, sizeof(servaddr));
 	servaddr.sin_family = AF_INET;
 	servaddr.sin_port   = htons(13);	/* daytime server */
 	if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
 		err_quit("inet_pton error for %s", argv[1]);
 
 	if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
 		err_sys("connect error");
 
 	while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
 		recvline[n] = 0;	/* null terminate */
 		if (fputs(recvline, stdout) == EOF)
 			err_sys("fputs error");
 	}
 	if (n < 0)
 		err_sys("read error");
 
 	exit(0);
 
 
 
 
  Функция socket создает потоковый сокет (SOCK_STREAM) и возвращает 
 целочисленный дескриптор.
 Если ее вызов оказывается неудачным , выполнение программы прерывается 
 с помощью err_sys .
  Структура sockaddr_inc - заполняется ip-адресом сервера и 
 номером порта сервера .
 Ip-адрес и номер порта должны иметь специфический формат , 
 который формируется с помощью 
 htons (для порта) и inet_pton .
  Далее функция connect устанавливает соединение с сервером , 
  который должен быть запущен раньше .
  Чтение и отображение ответа сервера выполняется с помощью 
  стандартной функции fputs .
   Сокеты - процесс потоковый и циклический , и для этого используется цикл ,
   внутри которого работает функция read . И цикл этот может быть прерван двояко -
   когда read возвращает 0 (соединение разорвано , поскольку передача закончена ) 
   либо -1 (произошла ошибка) .
 Стивенс использует т.н. функции-обертки , например функция-обертка для socket ,
 которую можно найти в каталоге /lib/wrapsock.c :
 int
 Socket(int family, int type, int protocol)
 {
 	int		n;
 
 	if ( (n = socket(family, type, protocol)) < 0)
 		err_sys("socket error");
 	return(n);
 }
  Удобство в их использовании в том , что они сами обрабатывают ошибки и 
 возвращают нужные коды .
  Если системная ("ядрёная") юниксовая функция вызывает ошибку , 
  глобальной переменной errno
 присваивается положительное значение . Эти значения определены в sys/errno.h .
   Код сервера выглядит так :
 
 	int			listenfd, connfd;
 	struct sockaddr_in	servaddr;
 	char			buff[MAXLINE];
 	time_t			ticks;
 
 	listenfd = Socket(AF_INET, SOCK_STREAM, 0);
 
 	bzero(&servaddr, sizeof(servaddr));
 	servaddr.sin_family      = AF_INET;
 	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 	servaddr.sin_port        = htons(13);	/* daytime server */
 
 	Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
 
 	Listen(listenfd, LISTENQ);
 
 	for ( ; ; ) {
 		connfd = Accept(listenfd, (SA *) NULL, NULL);
 
         ticks = time(NULL);
         snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
         Write(connfd, buff, strlen(buff));
 
 		Close(connfd);
 	}
   
 
   Функция bind связывает порт сервера с клиентом . 
   Вызов функций socket , bind , listen - обычная последовательность 
   для любого tcp-сервера.
   Функция accept полностью блокирует сервер до тех пор , пока он не соединится .
   Соединение устанавливается с помощью т.н. 3-этажного рукопожатия , 
   accept возвращает присоединенный дескриптор .
    Соединение закрывается с помощью функции close .
   Показанный сервер последовательный , т.е. нескольких клиентов он может обслужить
   лишь по очереди . Для создания параллельного сервера нужно использовать 
   fork() либо threads .
   
    
   
На следующем рисунке представлена модель взаимодействия открытых систем - Open System Interconnection - где она сравнивается со стеком протоколов интернета .
2 нижних уровня OSI соответствуют аппаратному обеспечению , программиста оно мало касается , отсюда нужно лишь знать MTU - максимальную единицу передачи . Сетевой уровень - это IPV4 / IPV6 . Транспортный уровень - это TCP/UDP . 3 верхних уровня соответствуют уровню приложения . В этой книге описываются сокеты , которые являются интерфейсом между уровнем приложений и транспортным уровнем .

В юниксе для получения системной сетевой информации есть несколько команд :

  
 	1 netstat -ni : дает информацию об интерфейсах
 	  netstat -nl : показывает активные соединения
 	  netstat -rn : показывает таблицу маршрутизации
 	
 	2 ifconfig eth0 : получить информацию для интерфейса
 
 	3 ping  
  	 
 

Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье