// for ( refreshesLeft ) /// <summary>Broadcast a remote procedure call to several ONC/RPC servers.</summary> /// <remarks> /// Broadcast a remote procedure call to several ONC/RPC servers. For this /// you'll need to specify either a multicast address or the subnet's /// broadcast address when creating a <code>OncRpcUdpClient</code>. For /// every reply received, an event containing the reply is sent to the /// OncRpcBroadcastListener <code>listener</code>, which is the last /// parameter to the this method. /// <p>In contrast to the /// <see cref="OncRpcClient.call(int, XdrAble, XdrAble)">OncRpcClient.call(int, XdrAble, XdrAble) /// </see> /// method, /// <code>broadcastCall</code> will only send the ONC/RPC call once. It /// will then wait for answers until the timeout as set by /// <see cref="OncRpcClient.setTimeout(int)">OncRpcClient.setTimeout(int)</see> /// expires without resending the reply. /// <p>Note that you might experience unwanted results when using /// authentication types other than /// <see cref="OncRpcClientAuthNone">OncRpcClientAuthNone</see> /// , causing /// messed up authentication protocol handling objects. This depends on /// the type of authentication used. For <code>AUTH_UNIX</code> nothing /// bad happens as long as none of the servers replies with a shorthand /// verifier. If it does, then this shorthand will be used on all subsequent /// ONC/RPC calls, something you probably do not want at all. /// </remarks> /// <param name="procedureNumber">Procedure number of the procedure to call.</param> /// <param name="params"> /// The parameters of the procedure to call, contained /// in an object which implements the /// <see cref="XdrAble">XdrAble</see> /// interface. /// </param> /// <param name="result"> /// The object receiving the result of the procedure call. /// Note that this object is reused to deserialize all incomming replies /// one after another. /// </param> /// <param name="listener"> /// Listener which will get an /// <see cref="OncRpcBroadcastEvent">OncRpcBroadcastEvent</see> /// for every reply received. /// </param> /// <exception cref="OncRpcException">if an ONC/RPC error occurs.</exception> /// <exception cref="org.acplt.oncrpc.OncRpcException"></exception> public virtual void broadcastCall(int procedureNumber, org.acplt.oncrpc.XdrAble @params , org.acplt.oncrpc.XdrAble result, org.acplt.oncrpc.OncRpcBroadcastListener listener ) { lock (this) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to broadcast all its data. // Then wait for answers, receive and decode them one at a time. // nextXid(); org.acplt.oncrpc.OncRpcClientCallMessage callHeader = new org.acplt.oncrpc.OncRpcClientCallMessage (xid, program, version, procedureNumber, auth); org.acplt.oncrpc.OncRpcClientReplyMessage replyHeader = new org.acplt.oncrpc.OncRpcClientReplyMessage (auth); // // Broadcast the call. Note that we send the call only once and will // never resend it. // try { // // Send call message to server. Remember that we've already // "connected" the datagram socket, so java.net knows whom // to send the datagram packets. // sendingXdr.beginEncoding(host, port); callHeader.xdrEncode(sendingXdr); @params.xdrEncode(sendingXdr); sendingXdr.endEncoding(); } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTSEND , e.Message)); } // // Now enter the great loop where sit waiting for replies to our // broadcast call to come in. In every case, we wait until the // (total) timeout expires. // DateTime stopTime = DateTime.Now + new TimeSpan(timeout); do { try { // // Calculate timeout until the total timeout is reached, so // we can try to meet the overall deadline. // TimeSpan currentTimeout = (stopTime - DateTime.Now); if (currentTimeout.Ticks < 0) { currentTimeout = new TimeSpan(0); } socket.ReceiveTimeout = currentTimeout.Seconds; // // Then wait for datagrams to arrive... // receivingXdr.beginDecoding(); replyHeader.xdrDecode(receivingXdr); // // Only deserialize the result, if the reply matches the call // and if the reply signals a successful call. In case of an // unsuccessful call (which mathes our call nevertheless) throw // an exception. // if (replyHeader.messageId == callHeader.messageId) { if (!replyHeader.successfullyAccepted()) { // // We got a notification of a rejected call. We silently // ignore such replies and continue listening for other // replies. // receivingXdr.endDecoding(); } result.xdrDecode(receivingXdr); // // Notify a potential listener of the reply. // if (listener != null) { org.acplt.oncrpc.OncRpcBroadcastEvent evt = new org.acplt.oncrpc.OncRpcBroadcastEvent (this, receivingXdr.getSenderAddress(), procedureNumber, @params, result); listener.replyReceived(evt); } // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); } else { // // This should raise no exceptions, when skipping the UDP // record. So if one is raised, we will rethrow an ONC/RPC // exception instead. // try { receivingXdr.endDecoding(); } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTRECV , e.Message)); } } } catch (SocketException) { } catch (System.IO.IOException e) { // // Note that we only catch timeouts here, but no other // exceptions. Those others will go up further until someone // catches them. If we get the timeout we know that it // could be time to leave the stage and so we fall through // to the total timeout check. // // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTRECV , e.Message)); } }while (DateTime.Now < stopTime); return; } }
// // List of addresses of portmappers that replied to our call... // // // Remember addresses of replies for later processing. Please note // that you should not do any lengthy things (like DNS name lookups) // in this event handler, as you will otherwise miss some incomming // replies because the OS will drop them. // public virtual void replyReceived(org.acplt.oncrpc.OncRpcBroadcastEvent evt) { portmappers.add(evt.getReplyAddress()); System.Console.Out.Write("."); }
// for ( refreshesLeft ) /// <summary>Broadcast a remote procedure call to several ONC/RPC servers.</summary> /// <remarks> /// Broadcast a remote procedure call to several ONC/RPC servers. For this /// you'll need to specify either a multicast address or the subnet's /// broadcast address when creating a <code>OncRpcUdpClient</code>. For /// every reply received, an event containing the reply is sent to the /// OncRpcBroadcastListener <code>listener</code>, which is the last /// parameter to the this method. /// <p>In contrast to the /// <see cref="OncRpcClient.call(int, XdrAble, XdrAble)">OncRpcClient.call(int, XdrAble, XdrAble) /// </see> /// method, /// <code>broadcastCall</code> will only send the ONC/RPC call once. It /// will then wait for answers until the timeout as set by /// <see cref="OncRpcClient.setTimeout(int)">OncRpcClient.setTimeout(int)</see> /// expires without resending the reply. /// <p>Note that you might experience unwanted results when using /// authentication types other than /// <see cref="OncRpcClientAuthNone">OncRpcClientAuthNone</see> /// , causing /// messed up authentication protocol handling objects. This depends on /// the type of authentication used. For <code>AUTH_UNIX</code> nothing /// bad happens as long as none of the servers replies with a shorthand /// verifier. If it does, then this shorthand will be used on all subsequent /// ONC/RPC calls, something you probably do not want at all. /// </remarks> /// <param name="procedureNumber">Procedure number of the procedure to call.</param> /// <param name="params"> /// The parameters of the procedure to call, contained /// in an object which implements the /// <see cref="XdrAble">XdrAble</see> /// interface. /// </param> /// <param name="result"> /// The object receiving the result of the procedure call. /// Note that this object is reused to deserialize all incomming replies /// one after another. /// </param> /// <param name="listener"> /// Listener which will get an /// <see cref="OncRpcBroadcastEvent">OncRpcBroadcastEvent</see> /// for every reply received. /// </param> /// <exception cref="OncRpcException">if an ONC/RPC error occurs.</exception> /// <exception cref="org.acplt.oncrpc.OncRpcException"></exception> public virtual void broadcastCall(int procedureNumber, org.acplt.oncrpc.XdrAble @params , org.acplt.oncrpc.XdrAble result, org.acplt.oncrpc.OncRpcBroadcastListener listener ) { lock (this) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to broadcast all its data. // Then wait for answers, receive and decode them one at a time. // nextXid(); org.acplt.oncrpc.OncRpcClientCallMessage callHeader = new org.acplt.oncrpc.OncRpcClientCallMessage (xid, program, version, procedureNumber, auth); org.acplt.oncrpc.OncRpcClientReplyMessage replyHeader = new org.acplt.oncrpc.OncRpcClientReplyMessage (auth); // // Broadcast the call. Note that we send the call only once and will // never resend it. // try { // // Send call message to server. Remember that we've already // "connected" the datagram socket, so java.net knows whom // to send the datagram packets. // sendingXdr.beginEncoding(host, port); callHeader.xdrEncode(sendingXdr); @params.xdrEncode(sendingXdr); sendingXdr.endEncoding(); } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTSEND , e.Message)); } // // Now enter the great loop where sit waiting for replies to our // broadcast call to come in. In every case, we wait until the // (total) timeout expires. // DateTime stopTime = DateTime.Now + new TimeSpan(timeout); do { try { // // Calculate timeout until the total timeout is reached, so // we can try to meet the overall deadline. // TimeSpan currentTimeout = (stopTime - DateTime.Now); if (currentTimeout.Ticks < 0) { currentTimeout = new TimeSpan(0); } socket.ReceiveTimeout = currentTimeout.Seconds; // // Then wait for datagrams to arrive... // receivingXdr.beginDecoding(); replyHeader.xdrDecode(receivingXdr); // // Only deserialize the result, if the reply matches the call // and if the reply signals a successful call. In case of an // unsuccessful call (which mathes our call nevertheless) throw // an exception. // if (replyHeader.messageId == callHeader.messageId) { if (!replyHeader.successfullyAccepted()) { // // We got a notification of a rejected call. We silently // ignore such replies and continue listening for other // replies. // receivingXdr.endDecoding(); } result.xdrDecode(receivingXdr); // // Notify a potential listener of the reply. // if (listener != null) { org.acplt.oncrpc.OncRpcBroadcastEvent evt = new org.acplt.oncrpc.OncRpcBroadcastEvent (this, receivingXdr.getSenderAddress(), procedureNumber, @params, result); listener.replyReceived(evt); } // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); } else { // // This should raise no exceptions, when skipping the UDP // record. So if one is raised, we will rethrow an ONC/RPC // exception instead. // try { receivingXdr.endDecoding(); } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTRECV , e.Message)); } } } catch (SocketException) { } catch (System.IO.IOException e) { // // Note that we only catch timeouts here, but no other // exceptions. Those others will go up further until someone // catches them. If we get the timeout we know that it // could be time to leave the stage and so we fall through // to the total timeout check. // // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTRECV , e.Message)); } } while (DateTime.Now < stopTime); return; } }
/// <summary>Invoked when a reply to an ONC/RPC broadcast call is received.</summary> /// <remarks>Invoked when a reply to an ONC/RPC broadcast call is received.</remarks> /// <seealso cref="OncRpcBroadcastEvent">OncRpcBroadcastEvent</seealso> public virtual void replyReceived(org.acplt.oncrpc.OncRpcBroadcastEvent evt) { }