C 语言回调函数客户端简单示例
回调函数就是一个被作为参数传递的函数。在C语言中,回调函数只能使用函数指针实现,在C++、Python、ECMAScript等更现代的编程语言中还可以使用仿函数或匿名函数。 回调函数的使用可以大大提升编程的效率,这使得它在现代编程中被非常多地使用。同时,有一些需求必须要使用回调函数来实现。使用回调函数就会让别的程序员调用我们的代码时操作简单。 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
复制代码
|