Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

Рис. 5.5. TCP-соединение клиент-сервер с точки зрения клиента

Как мы отмечали в разделе 4.10, клиент может получить два локальных значения, выбранных ядром, вызвав функцию

getsockname
после установления соединения.

На рис. 5.6 показаны те же четыре значения, но с точки зрения сервера.

Рис. 5.6. TCP-соединение клиент-сервер с точки зрения сервера

Локальный порт (заранее известный порт сервера) задается функцией

bind
. Обычно сервер также задает в этом вызове универсальный IP-адрес, хотя может и ограничиться получением соединений, предназначенных для одного определенного локального интерфейса путем связывания с IP-адресом, записанным без символов подстановки (то есть не универсального). Если сервер связывается с универсальным IP-адресом на узле с несколькими сетевыми интерфейсами, он может определить локальный IP-адрес (указываемый как адрес отправителя в исходящих пакетах) при помощи вызова функции
getsockname
после установления соединения (см. раздел 4.10). Два значения удаленного адреса возвращаются серверу при вызове функции accept. Как мы отмечали в разделе 4.10, если сервером, вызывающим функцию accept, выполняется с помощью функции exec другая программа, то эта программа может вызвать функцию
getpeername
, чтобы при необходимости определить IP-адрес и порт клиента.

5.18. Формат данных

В нашем примере сервер никогда не исследует запрос, который он получает от клиента. Сервер лишь читает все данные, включая символ перевода строки, и отправляет их обратно клиенту, отслеживая только разделитель строк. Это исключение, а не правило, так как обычно необходимо принимать во внимание формат данных, которыми обмениваются клиент и сервер.

Пример: передача текстовых строк между клиентом и сервером

Изменим наш сервер так, чтобы он, по-прежнему принимая текстовую строку от клиента, предполагал, что строка содержит два целых числа, разделенных пробелом, и возвращал сумму этих чисел. Функции

main
наших клиента и сервера остаются прежними, как и функция
str_cli
. Меняется только функция
str_echo
, что мы показываем в листинге 5.11.

Листинг 5.11. Функция str_echo, суммирующая два числа

//tcpcliserv/str_echo08.c

1 #include "unp.h"

2 void

3 str_echo(int sockfd)

4 {

5 long arg1, arg2;

6 ssize_t n;

7 char line[MAXLINE];

8 for (;;) {

9 if ((n = Readline(sockfd, line, MAXLINE)) == 0)

10 return; /* соединение закрывается удаленным концом */

11 if (sscanf(line, "%ld%ld", &arg1, &arg2) == 2)

12 snprintf(line, sizeof(line), "%ld\n", arg1 + arg2);

13 else

14 snprintf(line, sizeof(line), "input error\n");

15 n = strlen(line);

16 Writen(sockfd, line, n);

17 }

18 }

11-14
Мы вызываем функцию
sscanf
, чтобы преобразовать два аргумента из текстовых строк в целые числа типа
long
, а затем функцию
snprintf
для преобразования результата в текстовую строку.

Эти клиент и сервер работают корректно вне зависимости от порядка байтов на их узлах.

Пример: передача двоичных структур между клиентом и сервером

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

long
(см. табл. 1.5).

Функции

main
наших клиента и сервера не изменяются. Мы определяем одну структуру для двух аргументов, другую структуру для результата и помещаем оба определения в наш заголовочный файл
sum.h
, представленный в листинге 5.12. В листинге 5.13 показана функция
str_cli
.

Листинг 5.12. Заголовочный файл sum.h

//tcpcliserv/sum.h

1 struct args {

2 long arg1;

3 long arg2;

4 };

5 struct result {

6 long sum;

7 };

Листинг 5.13. Функция str_cli, отправляющая два двоичных целых числа серверу

//tcpcliserv/str_cli09.c

1 #include "unp.h"

2 #include "sum.h"

3 void

4 str_cli(FILE *fp, int sockfd)

  • Читать дальше
  • 1
  • ...
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: