Чтение онлайн

ЖАНРЫ

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

135: * должна вернуть -1 и завершиться.

136: */

137: ufds[0].fd = STDIN_FILENO;

138: ufds[0].events = POLLIN;

139: ufds[1].fd = master;

140: ufds[1].events = POLLIN;

141:

142: do {

143: int r;

144:

145: r = poll(ufds, 2, -1);

146: if ((r < 0) && (errno != EINTR)) {

147: done = 1;

148: break;

149: }

150:

151: /*
сначала проверить возможность завершения */

152: if ((ufds[0].revents | ufds[1].revents) &

153: (POLLERR | POLLHUP | POLLNVAL)) {

154: done = 1;

155: break;

156: }

157:

158: if (propagate_sigwinch) {

159: /* обработчик сигнала запросил распространение SIGWINCH */

160: if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) {

161: perror("ptypair: не удается получить размеры окна");

162: }

163: if (ioctl(master, TIOCSWINSZ, &ws) < 0) {

164: perror("не удается восстановить размеры окна");

165: }

166:

167: /* не делать этого снова до поступления следующего SIGWINCH */

168: propagate_sigwinch = 0;

169:

170: /* опрос мог быть прерван SIGWINCH,

171: * потому повторить попытку. */

172: continue;

173: }

174:

175: if (ufds[1].revents & POLLIN) {

176: i = read (master, buf, BUFSIZE);

177: if (i >= 1) {

178: write(STDOUT_FILENO, buf, i);

179: } else {

180: done = 1;

181: }

182: }

183:

184: if (ufds[0].revents & POLLIN) {

185: i = read (STDIN_FILENO, buf, BUFSIZE);

186: if (i >= 1) {

187: write(master, buf, i);

188: } else {

189: done = 1;

190: }

191: }

192: } while (!done);

193:

194: tcsetattr(STDIN_FILENO, TCSANOW, &ot);

195: exit(0);

196: }

Вся добавленная сложность

ptytest.с
по сравнению с
forkptytest.с
связана с обработкой старого интерфейса. Все это было описано в данной главе, кроме запуска дочернего процесса, который рассматривался в главе 10.

Глава 17

Работа в сети с помощью сокетов

По мере того, как компьютерный мир все шире объединяется в единую сеть, важность сетевых приложений все больше и больше возрастает. Система Linux предлагает программный интерфейс сокетов Беркли (Беркли), который уже стал стандартным сетевым API. Мы рассмотрим основы использования сокетов Беркли и через сетевой протокол TCP/IP, и через простое межпроцессное взаимодействие (interprocess communication — IPC)

с помощью сокетов домена Unix.

Мы не планировали превратить данную главу в полное руководство по программированию для сетей. Это отдельная сложная тема, и для тех программистов, которые планируют серьезную работу с сокетами, мы рекомендуем специализированные книги по программированию для сетей, например, [33]. Этой главы, однако, будет достаточно для того, чтобы вы смогли создавать несложные сетевые приложения.

17.1. Поддержка протоколов

API-интерфейс сокетов Беркли был сконструирован в виде шлюза для нескольких протоколов. Хотя это и приводит к дополнительным сложностям в интерфейсе, это все- таки гораздо легче, чем создавать (или изучать) новый интерфейс для каждого нового протокола, который встречается в работе. В Linux используется интерфейс сокетов для многих протоколов, включая TCP/IP (версии 4 и 6), AppleTalk и IPX.

Мы обсудим применение сокетов для двух протоколов, доступных через реализацию сокетов Linux. Наиболее важным протоколом, поддерживаемым системой Linux, является TCP/IP [115] (Transmission Control Protocol/Internet Protocol — протокол управления передачей/протокол Internet), поскольку именно он управляет всем Internet. Мы также обратим внимание на сокеты домена Unix — механизм IPC, ограниченный одним компьютером. Хотя они и не работают через сеть, сокеты домена Unix широко применяются для приложений, работающих на одном компьютере.

115

Ядра 2.6.x, рассматриваемые в настоящей книге, поддерживают как версию 4, так и версию 6 (на последнюю обычно ссылаются как на IPv6 из набора TCP/IP).

Протоколы, как правило, используются группами, или семействами протоколов. Общераспространенное семейство протоколов TCP/IP среди прочих включает в себя протоколы TCP и UDP (User Datagram Protocol — протокол передачи дейтаграмм пользователя). Для того чтобы хорошо ориентироваться в различных протоколах, потребуется овладеть некоторой терминологией.

17.1.1. Идеальная работа в сети

Большинство пользователей ожидают от сетевых протоколов обеспечения эквивалента каналов Unix между компьютерами. Если байт (или последовательность байтов) поступает в один конец соединения, он обязательно выйдет из другого конца. Причем должен быть гарантирован не просто выход байта из другого конца, а выход непосредственно после того байта, который был отправлен перед ним, и перед байтом, посланным следующим. Конечно, все байты должны быть доставлены в первозданном виде без каких-либо изменений. Никакой другой процесс не может прерывать передачу дополнительными байтами; соединение ограничивается только двумя исходными сторонами.

Хорошей визуализацией этой идеи является телефон. При разговоре предполагается, что собеседник слышит те же самые слова и в том же порядке, что вы произносите.

17.1.2. Реальная работа в сети

Хотя все это кажется достаточно базовым, основные компьютерные сети работают далеко не так. Сеты склонны быть хаотическими и случайными. Представьте себе школьников на перемене, которым не только нельзя разговаривать, но и нужно находиться на расстоянии не менее пяти метров друг от друга. При этом они должны найти способ пообщаться — хотя бы с помощью бумажных самолетиков!

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

Поделиться с друзьями: