Archived

This forum has been archived. Please start a new discussion on GitHub.

Making C++ throughput demo oneway?

Ice-1.1.1:

To help me learn about Ice I thought I'd try adapting the Ice/demo/throughput
clients (C++ and Java) to use oneway messaging instead of twoway. I had
no problems with the Java version, but when I try to run my modified
Client.cpp I get:

sending and receiving 1 sequences of size 4096 (this may take a while)
BasicStream.cpp:464: Ice::UnmarshalOutOfBoundsException:
protocol error: out of bounds during unmarshaling

(I've also modified the program to accept repetitions and seqSize as
command line arguments, hence the change in the above message. This
code works fine in the twoway case.)

I built the oneway example following the example given in 16.10 of the
manual - the key code segment in the modified Client.cpp is:

Ice::ObjectPrx base = communicator->stringToProxy(proxy);
Ice::ObjectPrx oneway;
try {
oneway = base->ice_oneway();
}
catch (...) { // Couldn't compile with (const Ice::NoEndPointException &) per example?
cerr << "No endpoint for oneway invocations" << endl;
return EXIT_FAILURE;
}
ThroughputPrx throughput = ThroughputPrx::uncheckedCast(oneway);
if(!throughput)
{
cerr << argv[0] << ": invalid proxy" << endl;
return EXIT_FAILURE;
}

This compiles and builds, but dies on the later:

throughput->echoByteSeq(seq);

with the above message.

Can someone point me to what I've done wrong?

Thanks!

Comments

  • mes
    mes California
    Hi Steve,

    The most common reason for an UnmarshalOutOfBoundsException is invoking a twoway operation using a oneway proxy. The echoByteSeq operation cannot be invoked using a oneway proxy because it does not conform to oneway semantics; specifically, it has a non-void return value. The client-side run-time attempts to unmarshal the return value, which of course is not available when the operation is invoked with a oneway proxy.

    You should change your code to invoke sendByteSeq instead.

    Also, thanks for finding an error in the manual: the exception name should be Ice::NoEndpointException.

    - Mark
  • Re: Making C++ throughput demo oneway?
    Originally posted by SteveWampler
    Ice-1.1.1:

    but when I try to run my modified
    Client.cpp I get:

    sending and receiving 1 sequences of size 4096 (this may take a while)
    BasicStream.cpp:464: Ice::UnmarshalOutOfBoundsException:
    protocol error: out of bounds during unmarshaling

    [...]

    This compiles and builds, but dies on the later:

    throughput->echoByteSeq(seq);

    with the above message.

    Can someone point me to what I've done wrong?

    Thanks!

    Hi Steve,

    the error you are seeing is caused by trying to invoke an operation that returns a result via a oneway proxy. For oneway invocations, the operation must have a void return type, must not have any out parameters, and must not have an exception specification.

    The doc currently states that, in this case, you should get a TwowayOnlyException, but that isn't implemented in Ice 1.1.1 yet. I'm about to add this, so it will work as intended in Ice 1.2.

    The solution is not to call echoByteSeq() but sendByteSeq(). That operation doesn't return anything and can therefore be invoked via a oneway proxy.

    You will see the same error if you down-cast a oneway proxy from Object to its actual type using a checkedCast, because a checkedCast requires sending a message to the server and receiving a reply. So, to down-cast oneway proxies, you must always use an uncheckedCast.

    Cheers,

    Michi.
  • Originally posted by mes
    Hi Steve,

    Also, thanks for finding an error in the manual: the exception name should be Ice::NoEndpointException.

    - Mark

    Ah yes! I'll fix that for next version.

    Cheers,

    Michi.
  • Thanks - sendByteSeq() works like a charm!