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
 Part 3...299 
 Part 4...296 
 Kamran Husain...191 
 Commands...181 
 Secure Programming for Li...170 
 Stein-MacEachern-> Час...143 
 2.0-> Linux IP Networking...140 
 Ethreal 1...123 
 Сетунь...119 
 William Gropp...118 
 Python...117 
 Trees...117 
 Steve Pate 2...114 
 Steve Pate 3...109 
 Plusquellic 1...108 
 C++ Patterns 2...108 
 Part 2...108 
 Httpd-> История Ap...108 
 Redox...108 
 Ethreal 4...107 
 
  01.10.2020 : 2983014+ посещений 

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  
  	 
 

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

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

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