ping time out 을 구현하려는데....
질문을 또올립니다..
먼저 accept 가 이루어지면 user table 이 담긴 구조체를 넘겨받는 스레드가 생성이 됩니다.
구현하려는 방식은 클라이언트를 처리하는동안에 일정시간이 지나면 ping을 보내는 방법입니다.
회원테이블의 ping_answered 가 퐁을 받으면 1 이 세팅이 되고 핑을 보내면 0이 세팅이 됩니다.
메인 스레드 함수는 다음과 같습니다.
void *thread_process(void *args)
{
client_t* userinfo = (client_t*)args;
char *buffer;
int res;
/* 알람 시그널로인해 설정된 시간에 ping을 보내게됨.*/
pingtimeout_init((client_t*)userinfo);
buffer = emalloc(BUF_SIZE + 1);
/* 받는 메시지 처리 */
if((res = read_command(userinfo->fd, buffer, BUF_SIZE)) < 0) {
user_deconnect(userinfo, "Read error : connection reset by peer");
}
treat_command(buffer,userinfo);
}
다음은 pingtimeout_init함수입니다.
unsigned int pingtimeout_init(struct chat_client *client)
{
client_t* clientinfo = (client_t*)client;
timeout_delay = atoi(DEFAULT_PING_TIMEOUT);
if(timeout_delay){
signal(SIGALRM, alarm_handler);
alarm(timeout_delay);
}
return timeout_delay;
}
시그널 핸들 함수 //일정 시간이 되면 ping을 보내야 하는대..구조체를 받을 수 없는 문제점이 있내요.
구조체 포인터를 전역에 선언해버리니 다른 스레드에서 엑세스를 하게 되는 문제점이 있습니다.
void alarm_handler(int sig)
{
timeout_sendping(struct chat_client *client ); //<==이 구조체를 받을 수 가 없는 문제...
if(timeout_delay) {
signal(SIGALRM, alarm_handler);
alarm(timeout_delay);
}
}
int timeout_sendping(struct chat_client *client)
{
client_t* clientinfo = (client_t*)client;
if(clientinfo->login_complete) {
if(tmp_client->ping_answered == 0) {
user_deconnect(tmp_client, "ping timeout");
} else {
timeout_ping(tmp_client);
}
}
void timeout_ping(struct chat_client *the_client)
{
unsigned long timestamp = time(NULL);
the_client->ping_answered = 0;
send_generic_to(the_client, SEND_PING, "%u", timestamp);
}
select를 이용하는 방법을 어느분이 제시해주셨는대 구체적으로 어떻게 해야 되는건지 잘 모르겠내요.
select 를 이용하게 되면 로그인후 장시간 온라인 대기 상태는 다 time out현상으로 인식해버리는거 아닌가요?
구체적인 방법을 제시해 주시면 감사하겠습니다.
일단 ping을 구현하시려는 목적이 peer 가 살아 있는지 아닌지를 확
일단 ping을 구현하시려는 목적이 peer 가 살아 있는지 아닌지를 확인하려는 목적이라면 ping으로 구현하실 필요가 없습니다.
peer와의 connection이 끊어진 경우 select() 나 poll()에서 readable 한 fd로 return이 되고, read/write시에 확인이 가능합니다.
ping을 구현하시려는 목적이 다른데 있어서 꼭 필요하다면, 이와 같은 signal 방식으로는 불가능합니다.
heartbeat 을 구현하는 별도의 thread를 생성시키고, 이 thread가 가지는 구조체에 각각의 thread에서 원하는 interval과 호출되기를 원하는 function pointer, 전달될 parameter를 등록시키는 방법으로 구현하셔야 합니다.
이렇게 하면 원하는 function은 해당 thread의 context에서 실행되지 않고, heartbeat thread에서 실행될 것입니다.
다른 thread에서는 SIGALRM signal 을 masking 하고 heartbeat thread 만 signal 을 받도록 구현하시면 될겁니다.
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
댓글 달기