The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
UDP-сервер под xinetd, !*! Lex Grant, 11-Мрт-09, 18:27  [смотреть все]
Добрый день!

Столкнулся с трудностями с реализацией UDP-сервера, запускаемого из xinet.d. Задача элементарная: я с одной сетевой машины ("клиента") запускаю простенькую программку, она отправляет пакет на другую машину-сервер по определённому порту, слушаемому xinet.d, после чего происходит вызов моей программы-"сервера".

И если с протоколом TCP всё было ясно (смотрел вывод stdin и записывал его по fgets() в некоторый <char buffer[256]>), то у UDP всё гораздо серьёзнее. Запускаю на удалённой машине такой же простенький "клиент", он отдаёт сообщение на "сервер", моя программа-"сервер" запускается, но из stdin'а я абсолютно ничего не получаю. Нашёл в книжке такой пример ("Запуск приложения через inetd"). Здесь используется не вывод stdin, а следующая конструкция:

pid = sprintf(buf, "%d: ", getpid());
len = sizeof(peer);
rc = recvfrom(0, buf+pid, sizeof(buf)-pid, 0, (struct sockaddr*)&peer, &len);

Попробовал её, но и здесь результат - нулевой. Конфигурация конф. файла xinet.d такова:

service my_server
{
    disable         = no
    socket_type     = dgram
    flags           = REUSE
    instances       = 1
    wait            = yes
    protocol        = udp
    user            = root
    server          = /tmp/Server/my_server
    bind            = 192.168.0.3
    log_on_success  = HOST PID
    log_on_failure  = HOST
}

Вот фрагменты моего "клиента":

// в этой функции заполняю структуру адресов

static void set_address(char *, char *, struct sockaddr_in *, char *);

int main(int argc, char** argv)
{
const int on = 1;
int ident;
unsigned char* buffer = (unsigned char*) malloc(256);
struct sockaddr_in local;
struct sockaddr_in peer;
int s, s1, s2;

set_address(PEER_ADDRESS, PEER_PORT, &peer, "udp");
set_address(LOCAL_ADDRESS, LOCAL_PORT, &local, "udp");

srandom(time(NULL));


s = socket(PF_INET, SOCK_DGRAM, 0);
if (s<0) {printf("\nошибка вызова сокета\n");}


if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
   {
   printf("\nошибка вызова setsockopt\n");
   exit(-1);
   }

if (bind(s, (struct sockaddr *) &local, sizeof(local)))
   {
   printf("\nошибка вызова функции bind\n");
   printf(strerror(errno));
   printf("\n");
   exit(-1);
   }

......
// Я так понял, что данная функция возможна, но не обязательна

//s1 = connect (s, (struct sockaddr*) &peer, sizeof(peer));
//if (s1 < 0){printf("\nошибка вызова функции connect()\n"); exit(-1);}


// В буфер вставлены некоторые значения

s2 = sendto(s, buffer, sizeof(buffer), 0,(struct sockaddr*) &peer, sizeof(struct sockaddr_in) );

}

Не могли бы вы мне помочь - подсказать, как это всё на самом деле реализуется?

  • UDP-сервер под xinetd, !*! Lex Grant, 13:39 , 12-Мрт-09 (1)
    Проблема снята. На всякий случай привожу здесь результаты.

    Для UDP всё решается путём введения функции следующего вида:
    recvfrom(0, buffer, sizeof (buffer), 0, (struct sockaddr *)&peer, (socklen_t*)&len),

    где  0 - нулевой идентификатор ("как бы" сокета)
    peer - указатель на структуру sockaddr_in
    buffer - строковый массив
    len - преобразованный численный размер структуры peer

    Тогда, действительно, считываются данные, пришедшие на открытый сокет udp супер-сервера xinet.d.

    • UDP-сервер под xinetd, !*! jd2, 18:42 , 16-Мрт-09 (2)
      >где  0 - нулевой идентификатор ("как бы" сокета)

      Не "как бы", а самый что ни на есть настоящий сокет. Просто inetd передаёт его дочернему процессу (Вашему демону) в виде нулевого файлового дескриптора: man dup2(2). Кстати, в случае с TCP происходит абсолютно то же самое, а read(fd, buf, len) в данном случае, если я не ошибаюсь, полностью идентично вызову recv(fd, buf, len, 0).




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру