1. 程式人生 > 其它 >《回撥函式 —— 執行緒註冊回撥函式》

《回撥函式 —— 執行緒註冊回撥函式》

client.h

#ifndef _HY_TCP_H
#define _HY_TCP_H

typedef void (* recv_callback)(char *data, int len);//定義回撥
typedef struct param{
        recv_callback callback;
    } callback_param;

int tcp_dns_change(char *dns, char *str, int size);
int tcp_connect(char *IP,int PORT);
void tcp_disconnect(void);
int tcp_send(char
*buf); int tcp_recv(char *buf, int size); void *thread_recv(void *param); void tcp_register_callback(recv_callback cb); //呼叫回撥函式 #endif

client.c

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netinet/in
.h> #include <arpa/inet.h> #include <string.h> #include <netdb.h> #include <syslog.h> #include <pthread.h> #include <poll.h> #include "hy_tcp.h" int sockfd; enum { STATE_NOCONNECTED, //未連線 STATE_CONNECTED, //已連線 STATE_DISCONNECTE //連線斷開 }; int connect_state = STATE_NOCONNECTED;
int tcp_dns_change(char *dns, char *str, int size) { struct hostent *hptr; hptr = gethostbyname(dns); if (hptr == NULL) { syslog(LOG_ERR, "gethostbyname error"); return -1; } syslog(LOG_INFO, "ipaddr:%s\n", inet_ntop(hptr->h_addrtype, hptr->h_addr, str, size)); return 0; } int tcp_connect(char *IP,int PORT) { if (connect_state == STATE_NOCONNECTED) { struct sockaddr_in server_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { syslog(LOG_ERR, "create socket failed!\n"); return -1; } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr.s_addr = inet_addr(IP); if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { syslog(LOG_ERR, "connet error!\n"); return -1; } connect_state = STATE_CONNECTED; syslog(LOG_INFO, "connect success!\n"); return 0; } else return -1; } void tcp_disconnect(void) { if (connect_state != STATE_NOCONNECTED) { close(sockfd); syslog(LOG_INFO, "connect is break!\n"); } } int tcp_send(char *buf) { if (connect_state == STATE_CONNECTED) { return send(sockfd, buf, strlen(buf)+1, 0); } else return -1; } void *thread_recv(void *param) { int ret; static char buf[2048] = {0}; char heartbeat_buf[] = "heartbeat data"; callback_param *p = (callback_param *)param; struct pollfd c_poll; c_poll.fd = sockfd; c_poll.events = POLLIN; memset(buf, 0, sizeof(buf)); while (1) { if (connect_state == STATE_CONNECTED) { ret = poll(&c_poll, 1, 5000); if (ret < 0) { syslog(LOG_ERR, "poll error!\n"); break; } else if (0 == ret) { if (send(sockfd, heartbeat_buf, sizeof(heartbeat_buf), 0) < 0) { connect_state = STATE_DISCONNECTE; syslog(LOG_ERR, "disconnect!\n"); break; } } else { if (recv(sockfd, buf, sizeof(buf), 0) > 0) { syslog(LOG_INFO, "recv:%s\n", buf); p->callback(buf, sizeof(buf)); } } } else break; } } void tcp_register_callback(recv_callback cb) { pthread_t recv_t; static callback_param param; param.callback = cb; pthread_create(&recv_t, NULL, thread_recv, (void *)&param); pthread_detach(recv_t); }

main.c

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include "hy_tcp.h"
#include "hy_udp.h"

#define PORT 6000   //伺服器埠號
#if 1

void r_callback(char *msg, int len) {
    
}

int main(int argc, char *argv[])
{
    char recv_buf[1024] = {0};
    char send_buf[1024] = {0};
    char str[16];
    recv_callback func = r_callback;
    if(argc < 2){
        printf("required parameter missing\n");
        return -1;
    }
    //tcp_dns_change(argv[1], str, sizeof(str));
    tcp_connect(argv[1],PORT);
    tcp_register_callback(func);
    
    while(1){
        memset(send_buf,0,sizeof(send_buf));
        printf("please input something\n");
        scanf("%s",send_buf);
        tcp_send(send_buf);
    }
    tcp_disconnect();
    return 0;
}
#endif