• 《回调函数 —— 线程注册回调函数》


    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
  • 相关阅读:
    js设置与获取Cookie
    js,正则应用
    Ajax支持跨域之Web API实现
    RSA加密解密在jsencrypt+c#的实现-博客园加密登录
    转:sqlserver无法创建索引,超时时间已到解决办法
    【转】asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法
    c#连接SFTP上传文件
    mac 修改mysql root密码
    Vue学习手记09-mock与axios拦截的使用
    Vue学习手记08-vue-cli的启动过程
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/16293282.html
Copyright © 2020-2023  润新知