gRPC C++: client fails to connect to server

2,725 views
Skip to first unread message

ns1.s...@gmail.com

unread,
Jun 6, 2017, 6:42:20 PM6/6/17
to grpc.io
Pardon the newbie question. I am getting started with gRPC, and hitting a basic issue where the client gets an error code for the RPC call:
Error code: 14 Err msg: Endpoint read failed

TL;DR Server starts fine. Netstat shows it is listening on the port. Client fails to connect to netcat on same address as well.

The service is very simple:
<snip>
syntax = "proto3";

service MySvc { // name edited
   rpc GetVersion(Version) returns (Version) {}
}

message Version {
   int32 version = 1;
}
</snip>

The compilation succeeds with g++ 4.8.5 and  "-Wall". The server starts up fine and prints:
<snip>
I0606 16:17:24.415181976    4792 server_builder.cc:247]      Synchronous server. Num CQs: 1, Min pollers: 1, Max Pollers: 2147483647, CQ timeout (msec): 1000
Server listening on 127.0.0.1:50051
</snip>

The command 'netstat -tulpn | grep ...' shows that the server is listening:
tcp6       0      0 127.0.0.1:50051         :::*                    LISTEN      4792/./<service-name>

I also ran 'nc -l 127.0.0.1 50051' and executed the client binary. The netcat got nothing. So, the issue seems be on the client side.

Here is my client code:
<snip>
class MySvcClient {
public:
   MySvcClient(std::shared_ptr<Channel> channel)
        : stub_(MySvc::NewStub(channel)) {}

   int GetServerVersion(int version) {
      Version client_version, server_version;
      ClientContext ctx;

      client_version.set_version(version);
      Status status = stub_->GetVersion(&ctx, client_version, &server_version);

      cout << "Error code: " << status.error_code();
      cout << " Err msg: " << status.error_message() << endl;

      if (status.ok()) {
         cout << "Server version: " << server_version.version() << endl;
         return server_version.version();
      } else {
         cout << "Failed to get Server version: " << endl;
         return -1;
      }
   }

private:
   unique_ptr<MySvc::Stub> stub_;
};

int main(int argc, char** argv) {
   MySvcClient client(grpc::CreateChannel(
      "127.0.0.1:50051", grpc::InsecureChannelCredentials()));
   int myversion = 2;
   int server_version = client.GetServerVersion(myversion);
   cout << "Server version: " << server_version << endl;

   return 0;
}
</snip>

Makarand Dharmapurikar

unread,
Jun 7, 2017, 10:52:16 AM6/7/17
to ns1.s...@gmail.com, grpc.io
How about check what's happening on the network with wireshark?

--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+unsubscribe@googlegroups.com.
To post to this group, send email to grp...@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/c9a2c89e-ff6a-4f78-9949-2e626bfa36bc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sundar Nadathur

unread,
Jun 7, 2017, 7:41:30 PM6/7/17
to Makarand Dharmapurikar, grpc.io
Hi,
    I checked with wireshark as well, by listening on loopback interface in Linux. I also tried changing to a local IP already configured on an internal bridge and ran wireshark on that. Nothing comes out of the client.

After instrumenting the grpc code, I traced it to the grpc function BlockingUnaryCall(). I instrumented it as below, with the output in comments in red. Strangely, the status value changes from 0 to 14, the function returns 14 and the client code bails out. What am I missing?

template <class InputMessage, class OutputMessage>
Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
                         ClientContext* context, const InputMessage& request,
                         OutputMessage* result) {
  . . .
  Status status = ops.SendMessage(request);
  std::cout << __FUNCTION__ << ": Error code: " << status.error_code() << "\n"; //status=0
  if (!status.ok()) {
    return status;
  }
  std::cout << "Calling SendInitialMetadata\n"; // NSS
  ops.SendInitialMetadata(context->send_initial_metadata_,
                          context->initial_metadata_flags());
  ops.RecvInitialMetadata(context);
  ops.RecvMessage(result);
  ops.ClientSendClose();
  ops.ClientRecvStatus(context, &status);
  std::cout << "Called ClientRecvStatus: Status= " << status.error_code() << "\n"; 
//status=0
  call.PerformOps(&ops);
  std::cout << "Checking again: Status= " << status.error_code() << "\n";
// status=0
  if (cq.Pluck(&ops)) {
    std::cout << "cq.Pluck-ops is true, whatever that means.\n";
//This shows in output
    if (!ops.got_message && status.ok()) {
      std::cout << __FUNCTION__ << " returning code Unimplemented\n";
//Not in output
      return Status(StatusCode::UNIMPLEMENTED,
                    "No message returned for unary request");
    }
  } else {
    std::cout << __FUNCTION__ << " assert !status-ok\n";
//Not in output   
    GPR_CODEGEN_ASSERT(!status.ok());
  }
  std::cout << "Returning Status= " << status.error_code() << "\n";
// status=14!
  return status;
}


Thanks a lot,
Sundar

Makarand Dharmapurikar

unread,
Jun 7, 2017, 7:43:28 PM6/7/17
to Sundar Nadathur, grpc.io
Please run with logging turned on like so:
export GRPC_TRACE=all
export GRPC_VERBOSITY=DEBUG

Sundar Nadathur

unread,
Jun 7, 2017, 8:34:53 PM6/7/17
to Makarand Dharmapurikar, grpc.io
Thanks, Makarand. That worked. The client is trying to go through a proxy, even though I have configured no_proxy for 127.0.0.1 and the local IP. Unsetting http_proxy allowed the client to contact the server.

Now, I need to check why no_proxy did not work.

Regards,
Sundar

ns1.s...@gmail.com

unread,
Jun 7, 2017, 9:37:05 PM6/7/17
to grpc.io, maka...@google.com, ns1.s...@gmail.com
BTW, it is still not clear how the status variable changed from 0 to 14 in this snippet -- any clues?

  std::cout << "Checking again: Status= " << status.error_code() << "\n"; // status=0 here
  if (cq.Pluck(&ops)) {
    std::cout << "cq.Pluck-ops is true, whatever that means.\n"; 
//This shows in output
    if (!ops.got_message && status.ok()) {
      std::cout << __FUNCTION__ << " returning code Unimplemented\n"; 
//Not in output
      return Status(StatusCode::UNIMPLEMENTED,
                    "No message returned for unary request");
    }
  } else {
    std::cout << __FUNCTION__ << " assert !status-ok\n"; 
//Not in output    
    GPR_CODEGEN_ASSERT(!status.ok());
  }
  std::cout << "Returning Status= " << status.error_code() << "\n"; 
// status=14! 

Reply all
Reply to author
Forward
0 new messages