C 語言回調(diào)函數(shù)客戶端簡單示例
回調(diào)函數(shù)就是一個被作為參數(shù)傳遞的函數(shù)。在C語言中,回調(diào)函數(shù)只能使用函數(shù)指針實現(xiàn),在C++、Python、ECMAScript等更現(xiàn)代的編程語言中還可以使用仿函數(shù)或匿名函數(shù)。
回調(diào)函數(shù)的使用可以大大提升編程的效率,這使得它在現(xiàn)代編程中被非常多地使用。同時,有一些需求必須要使用回調(diào)函數(shù)來實現(xiàn)。使用回調(diào)函數(shù)就會讓別的程序員調(diào)用我們的代碼時操作簡單。
client.h:
#ifndef _HY_TCP_H
#define _HY_TCP_H
typedef void (* recv_callback)(char *data, int len);//定義回調(diào)
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); //調(diào)用回調(diào)函數(shù)
#endifclient.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 *)¶m);
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 //服務(wù)器端口號
#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
版權(quán)聲明:本文來源網(wǎng)絡(luò),免費傳達知識,版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請聯(lián)系我進行刪除。
???????????????? END ???????????????
關(guān)注我的微信公眾號,回復(fù)“加群”按規(guī)則加入技術(shù)交流群。
點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。
評論
圖片
表情
