谷动谷力

 找回密码
 立即注册
查看: 785|回复: 0
打印 上一主题 下一主题
收起左侧

C 语言回调函数客户端简单示例

[复制链接]
跳转到指定楼层
楼主
发表于 2023-3-7 19:27:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
C 语言回调函数客户端简单示例


回调函数就是一个被作为参数传递的函数。在C语言中,回调函数只能使用函数指针实现,在C++、Python、ECMAScript等更现代的编程语言中还可以使用仿函数或匿名函数。
回调函数的使用可以大大提升编程的效率,这使得它在现代编程中被非常多地使用。同时,有一些需求必须要使用回调函数来实现。使用回调函数就会让别的程序员调用我们的代码时操作简单。
client.h:
  1. #ifndef _HY_TCP_H
  2. #define _HY_TCP_H

  3. typedef void (* recv_callback)(char *data, int len);//定义回调
  4. typedef struct param{
  5.         recv_callback callback;
  6.     } callback_param;

  7. int tcp_dns_change(char *dns, char *str, int size);
  8. int tcp_connect(char *IP,int PORT);
  9. void tcp_disconnect(void);
  10. int tcp_send(char *buf);
  11. int tcp_recv(char *buf, int size);
  12. void *thread_recv(void *param);
  13. void tcp_register_callback(recv_callback cb); //调用回调函数

  14. #endif
复制代码

client.c:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/socket.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #include <string.h>
  9. #include <netdb.h>
  10. #include <syslog.h>
  11. #include <pthread.h>
  12. #include <poll.h>
  13. #include "hy_tcp.h"

  14. int sockfd;

  15. enum {
  16.     STATE_NOCONNECTED,  //未连接
  17.     STATE_CONNECTED,    //已连接
  18.     STATE_DISCONNECTE   //连接断开
  19. };

  20. int connect_state = STATE_NOCONNECTED;

  21. int tcp_dns_change(char *dns, char *str, int size)
  22. {
  23.     struct hostent *hptr;
  24.     hptr = gethostbyname(dns);
  25.     if (hptr == NULL) {
  26.         syslog(LOG_ERR, "gethostbyname error");
  27.         return -1;
  28.     }
  29.     syslog(LOG_INFO, "ipaddr:%s\n", inet_ntop(hptr->h_addrtype, hptr->h_addr, str, size));
  30.     return 0;
  31. }

  32. int tcp_connect(char *IP,int PORT)
  33. {
  34.     if (connect_state == STATE_NOCONNECTED) {
  35.         struct sockaddr_in server_addr;
  36.         sockfd = socket(AF_INET, SOCK_STREAM, 0);
  37.         if (sockfd < 0) {
  38.             syslog(LOG_ERR, "create socket failed!\n");
  39.             return -1;
  40.         }
  41.         memset(&server_addr, 0, sizeof(server_addr));
  42.         server_addr.sin_family = AF_INET;
  43.         server_addr.sin_port = htons(PORT);
  44.         server_addr.sin_addr.s_addr = inet_addr(IP);
  45.         if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
  46.             syslog(LOG_ERR, "connet error!\n");
  47.             return -1;
  48.         }
  49.         connect_state = STATE_CONNECTED;
  50.         syslog(LOG_INFO, "connect success!\n");
  51.         return 0;
  52.     }
  53.     else
  54.         return -1;
  55. }

  56. void tcp_disconnect(void)
  57. {
  58.     if (connect_state != STATE_NOCONNECTED) {
  59.         close(sockfd);
  60.         syslog(LOG_INFO, "connect is break!\n");
  61.     }
  62. }

  63. int tcp_send(char *buf)
  64. {
  65.     if (connect_state == STATE_CONNECTED) {
  66.         return send(sockfd, buf, strlen(buf)+1, 0);
  67.     }
  68.     else
  69.         return -1;
  70. }

  71. void *thread_recv(void *param)
  72. {
  73.     int ret;
  74.     static char buf[2048] = {0};
  75.     char heartbeat_buf[] = "heartbeat data";
  76.     callback_param *p = (callback_param *)param;
  77.     struct pollfd c_poll;
  78.     c_poll.fd = sockfd;
  79.     c_poll.events = POLLIN;
  80.     memset(buf, 0, sizeof(buf));
  81.     while (1) {

  82.         if (connect_state == STATE_CONNECTED) {
  83.             ret = poll(&c_poll, 1, 5000);
  84.             if (ret < 0) {
  85.                 syslog(LOG_ERR, "poll error!\n");
  86.                 break;
  87.             }
  88.             else if (0 == ret) {
  89.                 if (send(sockfd, heartbeat_buf, sizeof(heartbeat_buf), 0) < 0) {
  90.                     connect_state = STATE_DISCONNECTE;
  91.                     syslog(LOG_ERR, "disconnect!\n");
  92.                     break;
  93.                 }
  94.             }
  95.             else {
  96.                 if (recv(sockfd, buf, sizeof(buf), 0) > 0) {
  97.                     syslog(LOG_INFO, "recv:%s\n", buf);
  98.                     p->callback(buf, sizeof(buf));
  99.                 }
  100.             }
  101.         }
  102.         else
  103.             break;
  104.     }
  105. }

  106. void tcp_register_callback(recv_callback cb)
  107. {
  108.     pthread_t recv_t;
  109.     static callback_param param;
  110.     param.callback = cb;
  111.     pthread_create(&recv_t, NULL, thread_recv, (void *)param);
  112.     pthread_detach(recv_t);
  113. }
复制代码




main.c:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <string.h>
  6. #include <arpa/inet.h>
  7. #include "hy_tcp.h"
  8. #include "hy_udp.h"

  9. #define PORT 6000   //服务器端口号
  10. #if 1

  11. void r_callback(char *msg, int len) {
  12.    
  13. }

  14. int main(int argc, char *argv[])
  15. {
  16.     char recv_buf[1024] = {0};
  17.     char send_buf[1024] = {0};
  18.     char str[16];
  19.     recv_callback func = r_callback;
  20.     if(argc < 2){
  21.         printf("required parameter missing\n");
  22.         return -1;
  23.     }
  24.     //tcp_dns_change(argv[1], str, sizeof(str));
  25.     tcp_connect(argv[1],PORT);
  26.     tcp_register_callback(func);
  27.    
  28.     while(1){
  29.         memset(send_buf,0,sizeof(send_buf));
  30.         printf("please input something\n");
  31.         scanf("%s",send_buf);
  32.         tcp_send(send_buf);
  33.     }
  34.     tcp_disconnect();
  35.     return 0;
  36. }
  37. #endif
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-4-27 02:16 , Processed in 0.084525 second(s), 39 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表