Hello, all!
Интересует следующее: есть много соединений, проверяющихся через epoll (имеется ввиду уже открытых через accept).
Т.е. в цикле если приходят на нужный сокет (их несколько) данные, вызывается accept ( в параметрах передаю имя структуры для сохранения адреса) и уже дескриптор, вызванный accept, добавляется в очередь epoll на дальнейшую прослушку.
Итак, набрали мы тучу дескрипторов (открытых), но вот загвоздка - я вызываю функцию для обработки нужного дескриптора (не в том месте, где вызывается accept, а отдельно), все замечательно, но как узнать параметры соединения? К примеру, ip-адрес?
Дескриптор получаю из очереди через events[n].data.fd (где fd - дескриптор, открытый accept, ну а n это просто номер в очереди), т.е. данные, принятые в accept (структура с адресом, портом и т.д.) уже потеряна..
Есть ли способ из дескриптора открытого соединения получить данные об удаленной стороне? (с какого адреса подрубились там и пр.).
Спс.
man getsockname(2)P.S. Так путанно вопрос задать - это надо было постараться...
P.P.S. про getsockname(2) говорится в man socket(2) (это на будущее).
>man getsockname(2)
>
>P.S. Так путанно вопрос задать - это надо было постараться...
>
>P.P.S. про getsockname(2) говорится в man socket(2) (это на будущее).ну здесь в бОльшей степени тогда getpeername будет...
Но что sock, что peer выдают постоянно bad address, когда им суешь дескрипторы ..
Похожде действительно проще завести массив и заносить туда все дескрипторы с нужной информацией...
>ну здесь в бОльшей степени тогда 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;
}
Таблица.
дескриптор | - все связаные с ним данные, состояние, буфера, блокировки, итп.При обработке события - табличку читай и обновляй.
Не надо никаких таблиц, это ж 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...
...