Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
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  
  	 
 

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

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

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