Новые книги

Эта книга стала результатом эффективной практической работы авторов в российском бизнесе. Используя уникальный опыт организации бизнес-проектов, продаж и ведения переговоров с компаниями Coca-Cola, Olivetti, Seiko, Epson, различными инвесторами и звездами шоу-бизнеса, авторы рассказывают об особенностях продаж в России, где сделка часто проходит под влиянием личностных свойств и качеств продавца и покупателя. В книге вы найдете: 33 приема личных продаж, курс обучения переговорам, приводящим к заключению сделки, практические задания, помогающие развить такие важные для продавца навыки, как умение представлять товар и «раскодировать» запрос покупателя, выстраивать диалог с клиентом и направлять его к покупке, отстраиваться от конкурентов.

Издание поможет начинающим опытным продавцам ощутить свой потенциал, научиться эффективнее использовать уже накопленные навыки, совершенствовать личное мастерство. Она будет полезна как сотрудникам торговых компаний, торговым представителям, так и свободным предпринимателям.
The agile model of software development has taken the world by storm. Now, in Agile Software Development, Second Edition, one of agiles leading pioneers updates his Jolt Productivity award-winning book to reflect all that?s been learned about agile development since its original introduction.

Alistair Cockburn begins by updating his powerful model of software development as a ?cooperative game of invention and communication.? Among the new ideas he introduces: harnessing competition without damaging collaboration; learning lessons from lean manufacturing; and balancing strategies for communication. Cockburn also explains how the cooperative game is played in business and on engineering projects, not just software development

Next, he systematically illuminates the agile model, shows how it has evolved, and answers the questions developers and project managers ask most often, including

· Where does agile development fit in our organization?

· How do we blend agile ideas with other ideas?

· How do we extend agile ideas more broadly?

Cockburn takes on crucial misconceptions that cause agile projects to fail. For example, you?ll learn why encoding project management strategies into fixed processes can lead to ineffective strategy decisions and costly mistakes. You?ll also find a thoughtful discussion of the controversial relationship between agile methods and user experience design.

Cockburn turns to the practical challenges of constructing agile methodologies for your own teams. You?ll learn how to tune and continuously reinvent your methodologies, and how to manage incomplete communication. This edition contains important new contributions on these and other topics:

· Agile and CMMI

· Introducing agile from the top down

· Revisiting ?custom contracts?

· Creating change with ?stickers?

In addition, Cockburn updates his discussion of the Crystal methodologies, which utilize his ?cooperative game? as their central metaphor.

If you?re new to agile development, this book will help you succeed the first time out. If you?ve used agile methods before, Cockburn?s techniques will make you even more effective.

11.4 ГНЕЗДА

 

11.4 ГНЕЗДА

В предыдущем разделе было показано, каким образом взаимодействуют между собой процессы, протекающие на разных машинах, при этом обращалось внимание на то, что способы реализации взаимодействия могут быть различаться в зависимости от используемых протоколов и сетевых средств. Более того, эти способы не всегда применимы для обслуживания взаимодействия процессов, выполняющихся на одной и той же машине, поскольку в них предполагается существование обслуживающего (серверного) процесса, который при выполнении системных функций open или read будет приостанавливаться драйвером. В целях создания более универсальных методов взаимодействия процессов на основе использования многоуровневых сетевых протоколов для системы BSD был разработан механизм, получивший название "sockets" (гнезда) (см. [Berkeley 83]). В данном разделе мы рассмотрим некоторые аспекты применения гнезд (на пользовательском уровне представления).

Рисунок 11.18. Модель с использованием гнезд

Структура ядра имеет три уровня: гнезд, протоколов и устройств (Рисунок 11.18). Уровень гнезд выполняет функции интерфейса между обращениями к операционной системе (системным функциям) и средствами низких уровней, уровень протоколов содержит модули, обеспечивающие взаимодействие процессов (на рисунке упомянуты протоколы TCP и IP), а уровень устройств содержит драйверы, управляющие сетевыми устройствами. Допустимые сочетания протоколов и драйверов указываются при построении системы (в секции конфигурации); этот способ уступает по гибкости вышеупомянутому потоковому механизму. Процессы взаимодействуют между собой по схеме клиент-сервер: сервер ждет сигнала от гнезда, находясь на одном конце дуплексной линии связи, а процессы-клиенты взаимодействуют с сервером через гнездо, находящееся на другом конце, который может располагаться на другой машине. Ядро обеспечивает внутреннюю связь и передает данные от клиента к серверу.

Гнезда, обладающие одинаковыми свойствами, например, опирающиеся на общие соглашения по идентификации и форматы адресов (в протоколах), группируются в домены (управляемые одним узлом). В системе BSD 4.2 поддерживаются домены: "UNIX system" - для взаимодействия процессов внутри одной машины и "Internet" (межсетевой) - для взаимодействия через сеть с помощью протокола DARPA (Управление перспективных исследований и разработок Министерства обороны США) (см. [Postel 80] и [Postel 81]). Гнезда бывают двух типов: виртуальный канал (потоковое гнездо, если пользоваться терминологией Беркли) и дейтаграмма. Виртуальный канал обеспечивает надежную доставку данных с сохранением исходной последовательности. Дейтаграммы не гарантируют надежную доставку с сохранением уникальности и последовательности, но они более экономны в смысле использования ресурсов, поскольку для них не требуются сложные установочные операции; таким образом, дейтаграммы полезны в отдельных случаях взаимодействия. Для каждой допустимой комбинации типа домен-гнездо в системе поддерживается умолчание на используемый протокол. Так, например, для домена "Internet" услуги виртуального канала выполняет протокол транспортной связи (TCP), а функции дейтаграммы - пользовательский дейтаграммный протокол (UDP).

Существует несколько системных функций работы с гнездами. Функция socket устанавливает оконечную точку линии связи.

   sd = socket(format,type,protocol);

Format обозначает домен ("UNIX system" или "Internet"), type - тип связи через гнездо (виртуальный канал или дейтаграмма), а protocol - тип протокола, управляющего взаимодействием. Дескриптор гнезда sd, возвращаемый функцией socket, используется другими системными функциями. Закрытие гнезд выполняет функция close.

Функция bind связывает дескриптор гнезда с именем:

   bind(sd,address,length);

где sd - дескриптор гнезда, address - адрес структуры, определяющей идентификатор, характерный для данной комбинации домена и протокола (в функции socket). Length - длина структуры address; без этого параметра ядро не знало бы, какова длина структуры, поскольку для разных доменов и протоколов она может быть различной. Например, для домена "UNIX system" структура содержит имя файла. Процессы-серверы связывают гнезда с именами и объявляют о состоявшемся присвоении имен процессам-клиентам.

С помощью системной функции connect делается запрос на подключение к существующему гнезду:

   connect(sd,address,length);

Семантический смысл параметров функции остается прежним (см. функцию bind), но address указывает уже на выходное гнездо, образующее противоположный конец линии связи. Оба гнезда должны использовать одни и те же домен и протокол связи, и тогда ядро удостоверит правильность установки линии связи. Если тип гнезда - дейтаграмма, сообщаемый функцией connect ядру адрес будет использоваться в последующих обращениях к функции send через данное гнездо; в момент вызова никаких соединений не производится.

Пока процесс-сервер готовится к приему связи по виртуальному каналу, ядру следует выстроить поступающие запросы в очередь на обслуживание. Максимальная длина очереди задается с помощью системной функции listen:

   listen(sd,qlength)

где sd - дескриптор гнезда, а qlength - максимально-допустимое число запросов, ожидающих обработки.

Рисунок 11.19. Прием вызова сервером

Системная функция accept принимает запросы на подключение, поступающие на вход процесса-сервера:

   nsd = accept(sd,address,addrlen);

где sd - дескриптор гнезда, address - указатель на пользовательский массив, в котором ядро возвращает адрес подключаемого клиента, addrlen - размер пользовательского массива. По завершении выполнения функции ядро записывает в переменную addrlen размер пространства, фактически занятого массивом. Функция возвращает новый дескриптор гнезда (nsd), отличный от дескриптора sd. Процесс-сервер может продолжать слежение за состоянием объявленного гнезда, поддерживая связь с клиентом по отдельному каналу (Рисунок 11.19).

Функции send и recv выполняют передачу данных через подключенное гнездо. Синтаксис вызова функции send:

   count = send(sd,msg,length,flags);

где sd - дескриптор гнезда, msg - указатель на посылаемые данные, length размер данных, count - количество фактически переданных байт. Параметр flags может содержать значение SOF_OOB (послать данные out-of-band - "через таможню"), если посылаемые данные не учитываются в общем информационном обмене между взаимодействующими процессами. Программа удаленной регистрации, например, может послать out-of-band сообщение, имитирующее нажатие на клавиатуре терминала клавиши "delete". Синтаксис вызова системной функции recv:

   count = recv(sd,buf,length,flags);

где buf - массив для приема данных, length - ожидаемый объем данных, count количество байт, фактически переданных пользовательской программе. Флаги (flags) могут быть установлены таким образом, что поступившее сообщение после чтения и анализа его содержимого не будет удалено из очереди, или настроены на получение данных out-of-band. В дейтаграммных версиях указанных функций, sendto и recvfrom, в качестве дополнительных параметров указываются адреса. После выполнения подключения к гнездам потокового типа процессы могут вместо функций send и recv использовать функции read и write. Таким образом, согласовав тип протокола, серверы могли бы порождать процессы, работающие только с функциями read и write, словно имеют дело с обычными файлами.

Функция shutdown закрывает гнездовую связь:

   shutdown(sd,mode)

где mode указывает, какой из сторон (посылающей, принимающей или обеим вместе) отныне запрещено участие в процессе передачи данных. Функция сообщает используемому протоколу о завершении сеанса сетевого взаимодействия, оставляя, тем не менее, дескрипторы гнезд в неприкосновенности. Освобождается дескриптор гнезда только в результате выполнения функции close.

Системная функция getsockname получает имя гнездовой связи, установленной ранее с помощью функции bind:

   getsockname(sd,name,length);

Функции getsockopt и setsockopt получают и устанавливают значения различных связанных с гнездом параметров в соответствии с типом домена и протокола.

Рассмотрим обслуживающую программу, представленную на Рисунке 11.20. Процесс создает в домене "UNIX system" гнездо потокового типа и присваивает ему имя sockname. Затем с помощью функции listen устанавливается длина очереди поступающих сообщений и начинается цикл ожидания поступления запросов. Функция accept приостанавливает свое выполнение до тех пор, пока протоколом не будет зарегистрирован запрос на подключение к гнезду с означенным именем; после этого функция завершается, возвращая поступившему запросу новый дескриптор гнезда. Процесс-сервер порождает потомка, через которого будет поддерживаться связь с процессом-клиентом; родитель и потомок при этом закрывают свои дескрипторы, чтобы они не становились помехой для коммуникационного траффика другого процесса. Процесс-потомок ведет разговор с клиентом и завершается после выхода из функции read. Процесс-сервер возвращается к началу цикла и ждет поступления следующего запроса на подключение.


     #include <sys/types.h>                                     
     #include <sys/socket.h>                                    
                                                                
     main()                                                     
     {                                                          
         int sd,ns;                                             
         char buf[256];                                         
         struct sockaddr sockaddr;                              
         int fromlen;                                           
                                                                
         sd = socket(AF_UNIX,SOCK_STREAM,0);                    
                                                                
         /* имя гнезда - не может включать пустой символ */     
         bind(sd,"sockname",sizeof("sockname") - 1);            
         listen(sd,1);                                          
                                                                
         for (;;)                                               
         {                                                      
                                                                
              ns = accept(sd,&sockaddr,&fromlen);               
              if (fork() == 0)                                  
              {                                                 
                  /* потомок */                                 
                  close(sd);                                    
                  read(ns,buf,sizeof(buf));                     
                  printf("сервер читает '%s'\n",buf);           
                  exit();                                       
              }                                                 
              close(ns);                                        
         }                                                      
     }                                                          

Рисунок 11.20. Процесс-сервер в домене "UNIX system"


     #include <sys/types.h>                                     
     #include <sys/socket.h>                                    
                                                                
     main()                                                     
     {                                                          
        int sd,ns;                                              
        char buf[256];                                          
        struct sockaddr sockaddr;                               
        int fromlen;                                            
                                                                
        sd = socket(AF_UNIX,SOCK_STREAM,0);                     
                                                                
        /* имя в запросе на подключение не может включать       
        /* пустой символ */                                     
        if (connect(sd,"sockname",sizeof("sockname") - 1) == -1)
             exit();                                            
                                                                
        write(sd,"hi guy",6);                                   
     }                                                          

Рисунок 11.21. Процесс-клиент в домене "UNIX system"

На Рисунке 11.21 показан пример процесса-клиента, ведущего общение с сервером. Клиент создает гнездо в том же домене, что и сервер, и посылает запрос на подключение к гнезду с именем sockname. В результате подключения процесс-клиент получает виртуальный канал связи с сервером. В рассматриваемом примере клиент передает одно сообщение и завершается.

Если сервер обслуживает процессы в сети, указание о том, что гнездо принадлежит домену "Internet", можно сделать следующим образом:

   socket(AF_INET,SOCK_STREAM,0);

и связаться с сетевым адресом, полученным от сервера. В системе BSD имеются библиотечные функции, выполняющие эти действия. Второй параметр вызываемой клиентом функции connect содержит адресную информацию, необходимую для идентификации машины в сети (или адреса маршрутов посылки сообщений через промежуточные машины), а также дополнительную информацию, идентифицирующую приемное гнездо машины-адресата. Если серверу нужно одновременно следить за состоянием сети и выполнением локальных процессов, он использует два гнезда и с помощью функции select определяет, с каким клиентом устанавливается связь в данный момент.

Предыдущая глава || Оглавление || Следующая глава