C++调用RPC函数时返回语句时出现分段错误

x4shl7ld  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(118)

当我在客户端调用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,这是我期望的结果,但当服务器试图返回时,它抛出了一个分段错误。

vlurs2pr

vlurs2pr1#

代码中有一些反惯用的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;
}

相关问题