一、简单理解
函数指针
#include <iostream>
#include <string>
void Server(std::string translation)
{
std::cout << "I am a Server ,The words that the client needs to translate -> " << translation <<" <-> 苹果" << std::endl;
}
// 实现一个英文翻译 --> 这里先不这么复杂
// 客户端发来 apple
void Client(std::string word, void(*callback)(std::string))
{
std::cout << "I am a client this English is: " << word << std::endl;
callback(word);
}
int main()
{
Client("apple", Server);
return 0;
}
function
using func_t = std::function<void(std::string)>;
void Server(std::string translation)
{
std::cout << "I am a Server ,The words that the client needs to translate -> " << translation <<" <-> 苹果" << std::endl;
}
void Client(std::string word, func_t callback)
{
std::cout << "I am a client this English is: " << word << std::endl;
callback(word);
}
int main()
{
Client("apple", Server);
return 0;
}
Lambda
using func_t = std::function<void(std::string)>;
void Client(std::string word, func_t callback)
{
std::cout << "I am a client this English is: " << word << std::endl;
callback(word);
}
int main()
{
Client("apple", [](std::string word) {
std::cout << "I am a Server ,The words that the client needs to translate -> " << word << " <-> 苹果" << std::endl;
});
return 0;
}
仿函数
class Server
{
public:
void operator()(std::string translation)
{
std::cout << "I am a Server ,The words that the client needs to translate -> " << translation << " <-> 苹果" << std::endl;
}
};
void Client(std::string word, Server server)
{
std::cout << "I am a client this English is: " << word << std::endl;
server(word);
}
int main()
{
Server server;
Client("apple", server);
return 0;
}
所有函数的输出结果
I am a client this English is: apple
I am a Server ,The words that the client needs to translate -> apple <-> 苹果
二、实际应用
下面写一个很简单的回调实际应用
就是通过客户端发送一个apple,之后服务端通过回调进行发送一个苹果
UdpServer.h
using func_t = std::function<void(const std::string& , std::string* )>;
class UdpServer
{
public:
UdpServer(int port, func_t callback)
: _port(port), _sockfd(-1), _callback(callback)
{
}
~UdpServer()
{
if (_sockfd != -1)
{
::close(_sockfd);
}
}
bool Init()
{
// create socket
_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
std::cout << "Create socket: " << _sockfd << std::endl;
// bind socket
struct sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = ::htons(_port);
local.sin_addr.s_addr = INADDR_ANY;
int n = ::bind(_sockfd, (struct sockaddr *)(&local), sizeof(local));
std::cout << "Bind socket success: " << n << std::endl;
return true;
}
void Start()
{
while (true)
{
char inbuffer[1024];
struct sockaddr_in peer;
socklen_t len = sizeof(peer);
// 接受数据
ssize_t n = ::recvfrom(_sockfd, inbuffer, sizeof(inbuffer) - 1, 0, (struct sockaddr *)(&peer), &len);
if (n > 0)
{
inbuffer[n] = 0;
uint16_t clientport = ::ntohs(peer.sin_port); // 客户端port
std::string clientip = ::inet_ntoa(peer.sin_addr); // 客户端ip
std::cout << "Received message from " << clientip << ":" << clientport << " sockfd: " << _sockfd << " Message: " << inbuffer << std::endl;
std::string echo_string = "echo# ";
echo_string += inbuffer;
// 调用回调函数
_callback(inbuffer, &echo_string);
::sendto(_sockfd, echo_string.c_str(), echo_string.size(), 0, (struct sockaddr *)(&peer), len);
}
}
}
private:
int _port;
int _sockfd;
func_t _callback;
};
Dict.h
class Translation
{
public:
void translate(const std::string& word, std::string* transltion)
{
std::cout << "client: " << word << std::endl;
*transltion += " 苹果";
}
};
UdpServer.cpp
int main(int argc,char *argv[])
{
if(argc != 2)
{
std::cerr << "Usage: "<< argv[0] << " serverip serverport" << std::endl;
exit(1);
}
uint16_t serverport = std::stoi(argv[1]);
Translation t;
// 法一
// auto callback = std::bind(&Translation::translate,&t,std::placeholders::_1,std::placeholders::_2);
// UdpServer server(serverport,callback);
// 法二
UdpServer server(serverport,[&t] (const std::string& word, std::string* transltion) {
t.translate(word, transltion);
});
server.Init();
server.Start();
return 0;
}
UdpClient.cpp
int main(int argc,char *argv[])
{
if(argc != 3)
{
std::cerr << "Usage: "<< argv[0] << " serverip serverport" << std::endl;
exit(1);
}
std::string serverip = argv[1];
uint16_t serverport = std::stoi(argv[2]);
int sockfd = ::socket(AF_INET,SOCK_DGRAM,0);
// 1. 创建socket
if(sockfd < 0)
{
std::cerr << "socket error"<<std::endl;
exit(1);
}
// 1.1填充信息
struct sockaddr_in server;
memset(&server,0,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(serverport);
server.sin_addr.s_addr = ::inet_addr(serverip.c_str());
// 2. clientdone
while(true)
{
std::cout << "Please Enter# ";
std::string message;
std::getline(std::cin,message);
int n = ::sendto(sockfd,message.c_str(),message.size(),0,(struct sockaddr*)(&server),sizeof(server));
struct sockaddr_in temp;
socklen_t len = sizeof(temp);
char buffer[1024];
n = :: recvfrom(sockfd,buffer,sizeof(buffer) - 1,0,(struct sockaddr*)(&temp),&len);
if(n > 0)
{
buffer[n] = 0;
std::cout << buffer << std::endl;
}
}
return 0;
}
这里只输出了客户端的消息
Please Enter# apple
echo# apple 苹果
Please Enter#