当我在客户端调用 rpc 函数并发送一个整数作为参数时,服务器上的函数应该将整数转换为符号地址。当使用 callrpc 调用 RPC 函数时,整数被发送到服务器,服务器接收它,将其转换为符号地址,但在 return 语句中我遇到分段错误。
这是服务器代码:
#include <iostream>
#include <cstring>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/rpc.h>
#include <netdb.h>
char *from_number_to_symbolic(int number) {
struct sockaddr_in temp = { AF_INET, SOCK_STREAM, { number } };
static char symbolic[100];
getnameinfo((struct sockaddr *) &temp, sizeof(struct sockaddr_in), symbolic, 100, NULL, 0, 0);
std::cout << std::endl << symbolic << std::endl;
return symbolic;
}
int main(int argc, char *argv[])
{
registerrpc(42700, 1, 1,(char* (*)(char *)) from_number_to_symbolic, (xdrproc_t) xdr_int, (xdrproc_t) xdr_wrapstring);
svc_run();
return 0;
}
这是客户端代码:
#include <iostream>
#include <cstdlib>
#include <rpc/rpc.h>
#include <arpa/inet.h>
#include <netdb.h>
int from_numeric_to_int(char *numeric) {
struct in_addr number;
inet_pton(AF_INET, numeric, &number);
return number.s_addr;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
exit(1);
}
char **num_adrress = &argv[1];
int *int_adrress = new int;
*int_adrress = from_numeric_to_int(*num_adrress);
char **symbolic = new char*;
callrpc("127.0.0.1", 42700, 1, 1, (xdrproc_t) xdr_int, (char *)num_adrress, (xdrproc_t) xdr_wrapstring, symbolic);
std::cout << *symbolic << std::endl;
return 0;
}
我像这样运行服务器和客户端:
./server
,./client 64.233.166.94
。服务器打印 208-107-167-85-dynamic.midco.net
这是我期待的结果,但是当服务器尝试返回时它会抛出分段错误。
代码中存在一些反惯用的C++以及RPC API的错误使用。这是清理后的版本:
服务器:
#include <iostream>
#include <sys/socket.h>
#include <netdb.h>
#include <rpc/rpc.h>
#include <rpc/svc.h>
#include <rpc/xdr.h>
char *from_number_to_symbolic(char* number_arg) {
int number = *reinterpret_cast<int*>(number_arg); // <- fixed API usage
sockaddr_in temp = {AF_INET, SOCK_STREAM,
{static_cast<in_addr_t>(number)}, {}};
static char symbolic[100];
static char *symbolic_ret = symbolic; // <- fixed API usage
getnameinfo(reinterpret_cast<sockaddr*>(&temp), sizeof(sockaddr_in),
symbolic, 100, nullptr, 0, 0);
std::cout << std::endl << symbolic << std::endl;
return reinterpret_cast<char*>(&symbolic_ret); // <- fixed API usage
}
int main()
{
registerrpc(42700, 1, 1, from_number_to_symbolic,
reinterpret_cast<xdrproc_t>(xdr_int),
reinterpret_cast<xdrproc_t>(xdr_wrapstring));
svc_run();
return 0;
}
客户:
#include <iostream>
#include <cstdlib>
#include <rpc/rpc.h>
#include <arpa/inet.h>
#include <netdb.h>
int from_numeric_to_int(char* numeric) {
struct in_addr number;
inet_pton(AF_INET, numeric, &number);
return number.s_addr;
}
int main(int argc, char* argv[])
{
if (argc != 2)
{
exit(1);
}
int int_adrress = from_numeric_to_int(argv[1]);
char* symbolic = nullptr; // <- no need to allocate on the heap
auto ret = callrpc("127.0.0.1", 42700, 1, 1,
reinterpret_cast<xdrproc_t>(xdr_int),
reinterpret_cast<char*>(&int_adrress),
reinterpret_cast<xdrproc_t>(xdr_wrapstring),
reinterpret_cast<char*>(&symbolic));
clnt_perrno(static_cast<clnt_stat>(ret));
std::cout << symbolic << std::endl;
xdr_free(reinterpret_cast<xdrproc_t>(xdr_wrapstring),
&symbolic); // <-- memory leak fix
return 0;
}