
回調(diào)函數(shù)就是一個(gè)被作為參數(shù)傳遞的函數(shù)。在C語(yǔ)言中,回調(diào)函數(shù)只能使用函數(shù)指針實(shí)現(xiàn),在C++、Python、ECMAScript等更現(xiàn)代的編程語(yǔ)言中還可以使用仿函數(shù)或匿名函數(shù)。
回調(diào)函數(shù)的使用可以大大提升編程的效率,這使得它在現(xiàn)代編程中被非常多地使用。同時(shí),有一些需求必須要使用回調(diào)函數(shù)來(lái)實(shí)現(xiàn)。使用回調(diào)函數(shù)就會(huì)讓別的程序員調(diào)用我們的代碼時(shí)操作簡(jiǎn)單。
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?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?"hy_tcp.h"
int?sockfd;
enum?{
????STATE_NOCONNECTED,??//未連接
????STATE_CONNECTED,????//已連接
????STATE_DISCONNECTE???//連接斷開(kāi)
};
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?
#include?
#include?
#include?
#include?
#include?
#include?"hy_tcp.h"
#include?"hy_udp.h"
#define?PORT?6000???//服務(wù)器端口號(hào)
#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)聲明:本文來(lái)源網(wǎng)絡(luò),免費(fèi)傳達(dá)知識(shí),版權(quán)歸原作者所有。如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系我進(jìn)行刪除。
???????????????? ?END ????????????????
關(guān)注我的微信公眾號(hào),回復(fù)“加群”按規(guī)則加入技術(shù)交流群。
點(diǎn)擊“閱讀原文”查看更多分享,歡迎點(diǎn)分享、收藏、點(diǎn)贊、在看。