/* Адреса транспортных узлов сервера и клиента */
struct sockaddr_in serv_addr, *clnt_addr;
struct hostent *hp;
char buf[80], hname[80];
struct t_bind req;
struct t_call *call;
/* Создадим транспортный узел. В качестве поставщика
транспортных услуг выберем модуль TCP */
if ((tn = t_open("/dev/tcp", O_RDWR, NULL)) == -1) {
t_error("Ошибка вызова t_open()");
exit(1);
}
/* Зададим адрес транспортного узла — он должен быть
известен клиенту */
nport = PORTNUM;
/* Приведем в соответствие порядок следования байтов для хоста
и сети */
nport = htons((u_short)nport);
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = nport;
req.addr.maxlen = sizeof(serv_addr);
req.addr.len = sizeof(serv_addr);
req.addr.buf = (char*)&serv_addr;
/* Максимальное число запросов, ожидающих обработки,
установим равным 5 */
req.qlen = 5;
/* Свяжем узел с запросом */
if (t_bind(tn, &req, (struct t_bind*)0) < 0) {
t_error("Ошибка вызова t_bind();
exit(1);
}
fprintf(stderr, "Адрес сервера: %s\n",
inet_ntoa(serv_addr.sin_addr));
/* Поскольку в структуре t_call нам понадобится только буфер
для хранения адреса клиента, разместим ее динамически */
if ((call =
(struct t_call*)t_alloc(tn, T_CALL, T_ADDR)) == NULL) {
t_error("Ошибка вызова t_alloc()");
exit(2);
}
call->addr.maxlen = sizeof(serv_addr);
call->addr.len = sizeof(srv_addr);
call->opt.len = 0;
call->update.len = 0;
/* Бесконечный цикл получения и обработки запросов */
while (1) {
/* Ждем поступления запроса на установление соединения */
if (t_listen(s, call) < 0) {
t_error("Ошибка вызова t_listen()");
exit(1);
}
/* Выведем информацию о клиенте, сделавшем запрос */
clnt_addr = (struct sockaddr_in*)call->addr.buf;
printf("Клиент: %s\n", inet_ntoa(clnt_addr->sin_addr));
/* Создадим транспортный узел для обслуживания запроса */
if (ntn = t_open("/dev/tcp", O_RDWR, (struct t_info*)0)) < 0) {
t_error("Ошибка вызова t_open()");
exit(1);
}
/* Пусть система сама свяжет его с подходящим адресом */
if (t_bind(ntn, (struct t_bind*)0), (struct t_bind*)0) < 0) {
t_error("Ошибка вызова t_accept()");
exit(1);
}
/* Примем запрос и переведем его обслуживание на новый
транспортный узел */
if (t_accept(tn, ntn, call) < 0) {
t_error("Ошибка вызова t_accept()");
exit(1);
}
/* Создадим новый процесс для обслуживания запроса.
При этом родительский процесс продолжает принимать
запросы от клиентов */
if ((pid = fork()) == -1) {
t_error("Ошибка вызова fork()");
exit(1);
}
if (pid == 0) {
int nbytes;
/* Дочерний процесс: этот транспортный узел уже не нужен,
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии