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
Последние статьи :
  Тренажёр 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...3163 
 Trees...1530 
 William Gropp...1488 
 Ethreal 3...1446 
 C++ Patterns 3...1435 
 Ethreal 4...1427 
 Максвелл 3...1419 
 Rodriguez 6...1417 
 Максвелл 5...1413 
 Go Web ...1408 
 Httpd-> История Ap...1407 
 Ext4 FS...1407 
 Kamran Husain...1404 
 Стивенс 9...1401 
 Robert Love 5...1398 
 K&R 1...1397 
 Erlang...1391 
 OS ->Intel Manual 1...1390 
 Perl OOP...1388 
 Rubni-Corbet -> Глав...1385 
 
  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  
  	 
 

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

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

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