⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eventlib.c

📁 linux的事件机制
💻 C
字号:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdarg.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include "eventLib.h"

int 
_send_frame(SOCKET s_dest, struct event_frame *p_out){
    int i_send_out = 0;
    LONG ul_send_left = sizeof(*p_out);
    BYTE *p_send_buffer = (BYTE *)p_out;
    time_t now = time((time_t*)NULL);

    if ((NULL == p_send_buffer)||(INVALID_SOCKET == s_dest)){
        return -1;
    }

    do {
        i_send_out = write(s_dest, p_send_buffer, ul_send_left);
        if (i_send_out < 0){
            perror("call to send:");
            return -1;
        }
        if (i_send_out >= ul_send_left){ 
            return 0;
        }
        p_send_buffer += i_send_out;
        ul_send_left -= i_send_out;
    }while(time((time_t*)NULL) - now < 3);
    debug_printf("send time out.\n");
    return -1;
}

int 
send_frame(struct sockaddr_in *server, struct event_frame *frame,\
           SOCKET *p_sock){
    int num_try;
    int con_ret = -1;
    struct  linger	m_sLinger;
    SOCKET s_link = INVALID_SOCKET;
    s_link = socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == s_link){
        perror("call socket");
        if (p_sock != NULL){
            *p_sock = INVALID_SOCKET;
        }
        return -1;
    }
    m_sLinger.l_onoff = 1; 
    m_sLinger.l_linger = 0; 
    setsockopt(s_link,\
               SOL_SOCKET,\
               SO_LINGER,\
               &m_sLinger,\
               sizeof(m_sLinger)\
               );

    for (num_try = 0; num_try < MAX_TRY_NUM; num_try++){
        con_ret = connect(s_link,\
                          (struct sockaddr*)server,\
                          sizeof(*server)\
                          );
        if (con_ret < 0){
            perror("call connect");
            continue;
        }
        /* now ,we can communicate */
        if (-1 == _send_frame(s_link, frame)){
            debug_printf("call _send_frame error\n");
            continue;
        }
        break;
    }

    if (num_try < MAX_TRY_NUM){
        if (p_sock == NULL){
            close_socket(&s_link);
        } else{
            *p_sock = s_link;
        }
        return 0;
    }else {
        if (p_sock != NULL){
            *p_sock = INVALID_SOCKET;
        }
        close_socket(&s_link);
        return -1;
    }
}

int
_receive_frame(SOCKET s_src, struct event_frame *p_in){
    int i_recv_in = 0;
    LONG ul_recv_left = sizeof(*p_in);
    BYTE *p_recv_buffer = (BYTE *)p_in;
    time_t now = time((time_t*)NULL);

    if ((NULL == p_recv_buffer)||(INVALID_SOCKET == s_src)){
        return -1;
    }

    do {
        i_recv_in = read(s_src, p_recv_buffer, ul_recv_left);
        if (i_recv_in < 0){
            perror("call to send:");
            return -1;
        }
        if (i_recv_in >= ul_recv_left){
            return 0;
        }
        p_recv_buffer += i_recv_in;
        ul_recv_left -= i_recv_in;
    }while(time((time_t*)NULL) - now < 5);
    debug_printf("receive time out.\n");
    return -1;
}

int 
receive_frame(SOCKET s_recv, struct event_frame *p_in){
    fd_set recv_fdset;
    FD_ZERO(&recv_fdset);
    FD_SET(s_recv, &recv_fdset);
		struct timeval timeout = {0};
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    select(s_recv + 1, &recv_fdset, NULL, NULL, &timeout);
    if (FD_ISSET(s_recv, &recv_fdset)){
    	  return _receive_frame(s_recv, p_in);
    } else{
        debug_printf("select time out\n");
        return -1;
    }
}

static int
name_safe_copy(char *dest, const char *src){
    if ((src == NULL) || (dest == NULL)){
        return -1;
    }
    int str_len = 0;
    str_len = strlen(src);
    memset(dest, 0, MAX_LEN_NAME+1);
    memcpy(dest, \
		       src, \
		       (str_len > MAX_LEN_NAME)? MAX_LEN_NAME: str_len\
		       );
    return 0;
} 

int 
client_register(pid_t pid, char *p_name, events_t events,\
                int num_sig, BOOL req_ignore){
    struct sockaddr_in s_register = {0};
    s_register.sin_family = AF_INET;
    s_register.sin_port = htons(EVENT_REGISTER_PORT);
    s_register.sin_addr.s_addr = inet_addr(EVENT_REGISTER_ADDR);

    struct event_frame f_reg;
    f_reg.type = FRAME_REGISTER;
    f_reg.body.reg.reg_pid = pid;
    f_reg.body.reg.reg_events = events;
    f_reg.body.reg.reg_sig = num_sig;
    f_reg.body.reg.reg_ignore = req_ignore;
    if (-1 == name_safe_copy(f_reg.body.reg.reg_name, p_name)){
        debug_printf("copy name error\n");
        return -1;
    }
    SOCKET s_reg = INVALID_SOCKET;
    if (-1 == send_frame(&s_register, &f_reg, &s_reg)){
    	  close_socket(&s_reg);
			  return -1;
		}
		
	  struct event_frame f_ack;
		if (-1 == receive_frame(s_reg, &f_ack)){
			  close_socket(&s_reg);
		    return -1;
		}
		if (FRAME_ACK == f_ack.type){
			  close_socket(&s_reg);
		    return f_ack.body.ack.ack_ok;
		}
	  close_socket(&s_reg);
    return -1;
}

#if defined UNREGISTER_SUPPORTED
int 
client_unregister(const char *p_name){
	  struct sockaddr_in s_unreg = {0};
    s_unreg.sin_family = AF_INET;
    s_unreg.sin_port = htons(EVENT_UNREG_PORT);
    s_unreg.sin_addr.s_addr = inet_addr(EVENT_UNREG_ADDR);

    struct event_frame f_unreg;
    f_unreg.type = FRAME_UNREGISTER;
    if (-1 == name_safe_copy(f_unreg.body.unreg.unreg_name, p_name)){
        debug_printf("copy name error\n");
        return -1;
    }

    return send_frame(&s_unreg, &f_unreg, NULL);
}
#endif

int 
events_inform(events_t events){
    /* create the remote info */
    struct sockaddr_in s_inform = {0};

    s_inform.sin_family = AF_INET;
    s_inform.sin_port = htons(EVENT_INFORM_PORT);
    s_inform.sin_addr.s_addr = inet_addr(EVENT_INFORM_ADDR);

    struct event_frame f_inform;
    f_inform.type = FRAME_INFORM;
    f_inform.body.inform.inf_events = events;

    return send_frame(&s_inform, &f_inform, NULL);
}

int 
client_request(char *p_name, events_t *events){
    struct sockaddr_in s_request = {0};
    s_request.sin_family = AF_INET;
    s_request.sin_port = htons(EVENT_REQUEST_PORT);
    s_request.sin_addr.s_addr = inet_addr(EVENT_REQUEST_ADDR);

    struct event_frame f_req;
    f_req.type = FRAME_REQUEST;
    if (-1 == name_safe_copy(f_req.body.request.request_name, p_name)){
        debug_printf("copy name error\n");
        *events = 0;
        return -1;
    }
    SOCKET s_req = INVALID_SOCKET;
    if (-1 == send_frame(&s_request, &f_req, &s_req)){
        close_socket(&s_req);
        *events = 0;
        return -1;
    }
    
    struct event_frame f_reponse;
		if (-1 == receive_frame(s_req, &f_reponse)){
			  close_socket(&s_req);
		    return -1;
		}
		if (FRAME_REPONSE != f_reponse.type){
			  close_socket(&s_req);
			  *events = 0;
        return -1;
		}
	  close_socket(&s_req);
    *events = f_reponse.body.reponse.reponse_events;
    return 0;
}

int 
send_ack(SOCKET s, BOOL sta){
    struct event_frame f_ack;
    f_ack.type = FRAME_ACK;
    f_ack.body.ack.ack_ok = sta;
    return _send_frame(s, &f_ack);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -