The OpenNET Project / Index page

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

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"UDP-сервер под xinetd"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"UDP-сервер под xinetd"  
Сообщение от Lex Grant (ok) on 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) );

}

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

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


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

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

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

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

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

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




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

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