Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Books
  Краткое описание
 Linux
 W. R. Стивенс TCP 
 W. R. Стивенс IPC 
 A.Rubini-J.Corbet 
 K. Bauer 
 Gary V. Vaughan 
 Д Вилер 
 В. Сталлинг 
 Pramode C.E. 
 Steve Pate 
 William Gropp 
 K.A.Robbins 
 С Бекман 
 Р Стивенс 
 Ethereal 
 Cluster 
 Languages
 C
 Perl
 M.Pilgrim 
 А.Фролов 
 Mendel Cooper 
 М Перри 
 Kernel
 C.S. Rodriguez 
 Robert Love 
 Daniel Bovet 
 Д Джеф 
 Максвелл 
 G. Kroah-Hartman 
 B. Hansen 
NEWS
Последние статьи :
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
  SQL 30.07   
  Python 10.06   
 
TOP 20
 Alg3...2143 
 Intel 386...782 
 Secure Programming for Li...682 
 Trees...661 
 Си за 21 день...577 
 2.0-> Linux IP Networking...574 
 Ethreal 1...567 
 Lists...564 
 Stein-MacEachern-> Час...561 
 Стивенс 1...554 
 Steve Pate 3...537 
 Ethreal 2...525 
 Rodriguez 6...500 
 Python...492 
 Стивенс 4...488 
 William Gropp...465 
 Advanced Bash Scripting G...456 
 Стивенс 5...427 
 Keogh 2...412 
 Комментарий...399 
 
  01.08.2020 : 2947670+ посещений 

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  
  	 
 

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

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

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