URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8447
[ Назад ]

Исходное сообщение
"Информация о подключенных сокетах"

Отправлено socket_select_nonblock , 26-Сен-09 20:11 
Hello, all!
Интересует следующее: есть много соединений, проверяющихся через epoll (имеется ввиду уже открытых через accept).
Т.е. в цикле если приходят на нужный сокет (их несколько) данные, вызывается accept ( в параметрах передаю имя структуры для сохранения адреса) и уже дескриптор, вызванный accept, добавляется в очередь epoll на дальнейшую прослушку.
Итак, набрали мы тучу дескрипторов (открытых), но вот загвоздка - я вызываю функцию для обработки нужного дескриптора (не в том месте, где вызывается accept, а отдельно), все замечательно, но как узнать параметры соединения? К примеру, ip-адрес?
Дескриптор получаю из очереди через events[n].data.fd (где fd - дескриптор, открытый accept, ну а n это просто номер в очереди), т.е. данные, принятые в accept (структура с адресом, портом и т.д.) уже потеряна..
Есть ли способ из дескриптора открытого соединения получить данные об удаленной стороне? (с какого адреса подрубились там и пр.).


Спс.


Содержание

Сообщения в этом обсуждении
"Информация о подключенных сокетах"
Отправлено jd , 26-Сен-09 22:49 
man getsockname(2)

P.S. Так путанно вопрос задать - это надо было постараться...

P.P.S. про getsockname(2) говорится в man socket(2) (это на будущее).


"Информация о подключенных сокетах"
Отправлено socket_select_nonblock , 29-Сен-09 18:40 
>man getsockname(2)
>
>P.S. Так путанно вопрос задать - это надо было постараться...
>
>P.P.S. про getsockname(2) говорится в man socket(2) (это на будущее).

ну здесь в бОльшей степени тогда getpeername будет...
Но что sock, что peer выдают постоянно bad address, когда им суешь дескрипторы ..
Похожде действительно проще завести массив и заносить туда все дескрипторы с нужной информацией...


"Информация о подключенных сокетах"
Отправлено jd , 30-Сен-09 03:48 
>ну здесь в бОльшей степени тогда getpeername будет...
>Но что sock, что peer выдают постоянно bad address, когда им суешь
>дескрипторы ..
>Похожде действительно проще завести массив и заносить туда все дескрипторы с нужной
>информацией...

Конечно, всё может быть (по поводу простоты и т.д.), но "Bad address" (errno = EFAULT) выдаётся по другому поводу:

ERRORS
...
       EFAULT  The name parameter points to memory not in a valid
               part of the process address space.

Только что попробовал - всё прекрасно работает: и getsockname, и getpeername:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>

#define PORT 10000

int main()
{ int ss, cs;
  struct sockaddr_in sa;
  socklen_t len;

  if( (ss = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  { perror("socket()");
    return 1;
  }

  memset(&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = htonl(INADDR_ANY);
  sa.sin_port = htons(PORT);
  if(bind(ss, (struct sockaddr*)&sa, sizeof(sa)) < 0)
  { perror("bind()");
    return 1;
  }

  if(listen(ss, 5) < 0)
  { perror("listen()");
    return 1;
  }

  if( (cs = accept(ss, NULL, NULL)) < 0)
  { perror("accept()"); return 1;
  }

  len = sizeof(sa);
  memset(&sa, 0, len);
  if(getpeername(cs, (struct sockaddr*)&sa, &len) < 0)
  { perror("getpeername()");
    return 1;
  }
  printf("remote peer: %s\n", inet_ntoa(sa.sin_addr));

  return 0;
}



"Информация о подключенных сокетах"
Отправлено svn , 29-Сен-09 15:25 
Таблица.
дескриптор | - все связаные с ним данные, состояние, буфера, блокировки, итп.

При обработке события - табличку читай и обновляй.


"Информация о подключенных сокетах"
Отправлено const86 , 30-Сен-09 12:24 
Не надо никаких таблиц, это ж epoll!

struct connection {
    int peer;
    struct sockaddr_storage peer_addr;
    // ещё куча полезной инфы
};

...
struct connection *cxn = malloc(...);
cxn->peer = accept(... &cxn->peer_addr);
struct epoll_event evt;
evt.data.ptr = cxn;
epoll_ctl(... &evt);
...

...
struct epoll_event evt;
epoll_wait(...&evt);
struct connection *cxn = evt.data.ptr;
// cxn->peer, cxn->peer_addr...
...