C 语言回调函数客户端简单示例
来源:嵌入式大杂烩发布时间:2023-02-27507浏览
询问 AI
来源:https://blog.csdn.net/weixin_45051519
回调函数就是一个被作为参数传递的函数。在C语言中,回调函数只能使用函数指针实现,在C++、Python、ECMAScript等更现代的编程语言中还可以使用仿函数或匿名函数。
回调函数的使用可以大大提升编程的效率,这使得它在现代编程中被非常多地使用。同时,有一些需求必须要使用回调函数来实现。使用回调函数就会让别的程序员调用我们的代码时操作简单。
client.h:
#ifndef_HY_TCP_H
#define_HY_TCP_H
typedefvoid(*recv_callback)(char*data,intlen);//定义回调
typedefstructparam{
recv_callbackcallback;
}callback_param;
inttcp_dns_change(char*dns,char*str,intsize);
inttcp_connect(char*IP,intPORT);
voidtcp_disconnect(void);
inttcp_send(char*buf);
inttcp_recv(char*buf,intsize);
void*thread_recv(void*param);
voidtcp_register_callback(recv_callbackcb);//调用回调函数
#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"
intsockfd;
enum{
STATE_NOCONNECTED,//未连接
STATE_CONNECTED,//已连接
STATE_DISCONNECTE//连接断开
};
intconnect_state=STATE_NOCONNECTED;
inttcp_dns_change(char*dns,char*str,intsize)
{
structhostent*hptr;
hptr=gethostbyname(dns);
if(hptr==NULL){
syslog(LOG_ERR,"gethostbynameerror");
return-1;
}
syslog(LOG_INFO,"ipaddr:%s\n",inet_ntop(hptr->h_addrtype,hptr->h_addr,str,size));
return0;
}
inttcp_connect(char*IP,intPORT)
{
if(connect_state==STATE_NOCONNECTED){
structsockaddr_inserver_addr;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
syslog(LOG_ERR,"createsocketfailed!\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,(structsockaddr*)server_addr,sizeof(server_addr))<0){
syslog(LOG_ERR,"conneterror!\n");
return-1;
}
connect_state=STATE_CONNECTED;
syslog(LOG_INFO,"connectsuccess!\n");
return0;
}
else
return-1;
}
voidtcp_disconnect(void)
{
if(connect_state!=STATE_NOCONNECTED){
close(sockfd);
syslog(LOG_INFO,"connectisbreak!\n");
}
}
inttcp_send(char*buf)
{
if(connect_state==STATE_CONNECTED){
returnsend(sockfd,buf,strlen(buf)+1,0);
}
else
return-1;
}
void*thread_recv(void*param)
{
intret;
staticcharbuf[2048]={0};
charheartbeat_buf[]="heartbeatdata";
callback_param*p=(callback_param*)param;
structpollfdc_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,"pollerror!\n");
break;
}
elseif(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;
}
}
voidtcp_register_callback(recv_callbackcb)
{
pthread_trecv_t;
staticcallback_paramparam;
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"
#definePORT6000//服务器端口号
#if1
voidr_callback(char*msg,intlen){
}
intmain(intargc,char*argv[])
{
charrecv_buf[1024]={0};
charsend_buf[1024]={0};
charstr[16];
recv_callbackfunc=r_callback;
if(argc<2){
printf("requiredparametermissing\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("pleaseinputsomething\n");
scanf("%s",send_buf);
tcp_send(send_buf);
}
tcp_disconnect();
return0;
}
#endif本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
在公众号聊天界面回复1024,可获取嵌入式资源;回复m,可查看文章汇总
新闻来源:嵌入式大杂烩,文中所述为作者独立观点,不代表icspec立场。更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj。
