protected override Msg XRecv(SendRecieveOptions flags) { // Deallocate old content of the message. Msg msg = null; if (m_pipe == null || (msg = m_pipe.Read ()) == null) { throw AgainException.Create(); } return msg; }
protected override Msg XRecv(SendRecieveOptions flags) { // Deallocate old content of the message. Msg msg = null; if (m_pipe == null || (msg = m_pipe.Read ()) == null) { ZError.ErrorNumber = (ErrorNumber.EAGAIN); // Initialise the output parameter to be a 0-byte message. return null; } return msg; }
protected override Msg XRecv(SendRecieveOptions flags) { Msg msg; // If we are in middle of sending a reply, we cannot receive next request. if (m_sendingReply) { throw NetMQException.Create("Cannot receive another request",ErrorCode.EFSM); throw new InvalidOperationException(); } // First thing to do when receiving a request is to copy all the labels // to the reply pipe. if (m_requestBegins) { while (true) { msg = base.XRecv (flags); if (msg == null) return null; if (msg.HasMore) { // Empty message part delimits the traceback stack. bool bottom = (msg.Size == 0); // Push it to the reply pipe. base.XSend (msg, flags); if (bottom) break; } else { // If the traceback stack is malformed, discard anything // already sent to pipe (we're at end of invalid message). base.Rollback(); } } m_requestBegins = false; } // Get next message part to return to the user. msg = base.XRecv (flags); if (msg == null) return null; // If whole request is read, flip the FSM to reply-sending state. if (!msg.HasMore) { m_sendingReply = true; m_requestBegins = true; } return msg; }
protected override Msg XRecv(SendRecieveOptions flags) { Msg msg = null; // If request wasn't send, we can't wait for reply. if (!m_receivingReply) { throw NetMQException.Create(ErrorCode.EFSM); } // First part of the reply should be the original request ID. if (m_messageBegins) { msg = base.XRecv(flags); if (msg == null) return null; // TODO: This should also close the connection with the peer! if (!msg.HasMore || msg.Size != 0) { while (true) { msg = base.XRecv(flags); Debug.Assert(msg != null); if (!msg.HasMore) break; } throw AgainException.Create(); } m_messageBegins = false; } msg = base.XRecv(flags); if (msg == null) return null; // If the reply is fully received, flip the FSM into request-sending state. if (!msg.HasMore) { m_receivingReply = false; m_messageBegins = true; } return msg; }
protected override Msg XRecv(SendRecieveOptions flags) { Msg msg = null; // If request wasn't send, we can't wait for reply. if (!m_receivingReply) { ZError.ErrorNumber = (ErrorNumber.EFSM); throw new InvalidOperationException("Cannot wait before send"); } // First part of the reply should be the original request ID. if (m_messageBegins) { msg = base.XRecv (flags); if (msg == null) return null; // TODO: This should also close the connection with the peer! if ( !msg.HasMore || msg.Size != 0) { while (true) { msg = base.XRecv (flags); Debug.Assert(msg != null); if (!msg.HasMore) break; } ZError.ErrorNumber = (ErrorNumber.EAGAIN); return null; } m_messageBegins = false; } msg = base.XRecv (flags); if (msg == null) return null; // If the reply is fully received, flip the FSM into request-sending state. if (!msg.HasMore) { m_receivingReply = false; m_messageBegins = true; } return msg; }
public Msg Recv(SendRecieveOptions flags) { if (m_ctxTerminated) { ZError.ErrorNumber = (ErrorNumber.ETERM); return null; } // Get the message. Msg msg = XRecv(flags); if (msg == null && !ZError.IsError(ErrorNumber.EAGAIN)) return null; // Once every inbound_poll_rate messages check for signals and process // incoming commands. This happens only if we are not polling altogether // because there are messages available all the time. If poll occurs, // ticks is set to zero and thus we avoid this code. // // Note that 'recv' uses different command throttling algorithm (the one // described above) from the one used by 'send'. This is because counting // ticks is more efficient than doing RDTSC all the time. if (++m_ticks == Config.InboundPollRate) { if (!ProcessCommands(0, false)) return null; m_ticks = 0; } // If we have the message, return immediately. if (msg != null) { ExtractFlags(msg); return msg; } // If the message cannot be fetched immediately, there are two scenarios. // For non-blocking recv, commands are processed in case there's an // activate_reader command already waiting int a command pipe. // If it's not, return EAGAIN. if ((flags & SendRecieveOptions.DontWait) > 0 || m_options.ReceiveTimeout == 0) { if (!ProcessCommands(0, false)) return null; m_ticks = 0; msg = XRecv(flags); if (msg == null) return null; ExtractFlags(msg); return msg; } // Compute the time when the timeout should occur. // If the timeout is infite, don't care. int timeout = m_options.ReceiveTimeout; long end = timeout < 0 ? 0 : (Clock.NowMs() + timeout); // In blocking scenario, commands are processed over and over again until // we are able to fetch a message. bool block = (m_ticks != 0); while (true) { if (!ProcessCommands(block ? timeout : 0, false)) return null; msg = XRecv(flags); if (msg != null) { m_ticks = 0; break; } if (!ZError.IsError(ErrorNumber.EAGAIN)) return null; block = true; if (timeout > 0) { timeout = (int)(end - Clock.NowMs()); if (timeout <= 0) { ZError.ErrorNumber = (ErrorNumber.EAGAIN); return null; } } } ExtractFlags(msg); return msg; }
protected virtual bool XSend(Msg msg, SendRecieveOptions flags) { throw new NotSupportedException("Must Override"); }
protected override Msg XRecv(SendRecieveOptions flags) { Msg msg = null; if (m_prefetched) { if (!m_identitySent) { msg = m_prefetchedId; m_prefetchedId = null; m_identitySent = true; } else { msg = m_prefetchedMsg; m_prefetchedMsg = null; m_prefetched = false; } m_moreIn = msg.HasMore; return msg; } Pipe[] pipe = new Pipe[1]; msg = m_fq.RecvPipe (pipe); // It's possible that we receive peer's identity. That happens // after reconnection. The current implementation assumes that // the peer always uses the same identity. // TODO: handle the situation when the peer changes its identity. while (msg != null && msg.IsIdentity ) msg = m_fq.RecvPipe (pipe); if (msg == null) return null; Debug.Assert(pipe[0] != null); // If we are in the middle of reading a message, just return the next part. if (m_moreIn) m_moreIn = msg.HasMore; else { // We are at the beginning of a message. // Keep the message part we have in the prefetch buffer // and return the ID of the peer instead. m_prefetchedMsg = msg; m_prefetched = true; Blob identity = pipe[0].Identity; msg = new Msg(identity.Data); msg.SetFlags(MsgFlags.More); m_identitySent = true; } return msg; }
protected override void XSend(Msg msg, SendRecieveOptions flags) { // If we are in the middle of receiving a request, we cannot send reply. if (!m_sendingReply) { throw NetMQException.Create("Cannot send another reply",ErrorCode.EFSM); } bool more = msg.HasMore; // Push message to the reply pipe. base.XSend (msg, flags); // If the reply is complete flip the FSM back to request receiving state. if (!more) m_sendingReply = false; }
// Receive a multi-part message // // Receives up to *count_ parts of a multi-part message. // Sets *count_ to the actual number of parts read. // ZMQ_RCVMORE is set to indicate if a complete multi-part message was read. // Returns number of message parts read, or -1 on error. // // Note: even if -1 is returned, some parts of the message // may have been read. Therefore the client must consult // *count_ to retrieve message parts successfully read, // even if -1 is returned. // // The iov_base* buffers of each iovec *a_ filled in by this // function may be freed using free(). // // Implementation note: We assume zmq::msg_t buffer allocated // by zmq::recvmsg can be freed by free(). // We assume it is safe to steal these buffers by simply // not closing the zmq::msg_t. // public int RecvIOv(SocketBase s, byte[][] a, int count, SendRecieveOptions flags) { if (s == null || !s.CheckTag()) { throw new InvalidOperationException(); } int nread = 0; bool recvmore = true; for (int i = 0; recvmore && i < count; ++i) { // Cheat! We never close any msg // because we want to steal the buffer. Msg msg = RecvMsg(s, flags); if (msg == null) { nread = -1; break; } // Cheat: acquire zmq_msg buffer. a[i] = msg.Data; // Assume zmq_socket ZMQ_RVCMORE is properly set. recvmore = msg.HasMore; } return nread; }
// Put the message to all active pipes. private void Distribute(Msg msg, SendRecieveOptions flags) { // If there are no matching pipes available, simply drop the message. if (m_matching == 0) { return; } for (int i = 0; i < m_matching; ++i) if(!Write (m_pipes[i], msg)) --i; // Retry last write because index will have been swapped }
public static int Send(SocketBase s, Msg msg, SendRecieveOptions flags) { int rc = SendMsg(s, msg, flags); if (rc < 0) { return -1; } return rc; }
public static int Send(SocketBase s, byte[] buf, int len, SendRecieveOptions flags) { if (s == null || !s.CheckTag()) { throw new InvalidOperationException(); } Msg msg = new Msg(len); msg.Put(buf, 0, len); int rc = SendMsg(s, msg, flags); if (rc < 0) { return -1; } return rc; }
// Sending functions. public static int Send(SocketBase s, String str, SendRecieveOptions flags) { byte[] data = Encoding.ASCII.GetBytes(str); return Send(s, data, data.Length, flags); }
public static Msg RecvMsg(SocketBase s, SendRecieveOptions flags) { return s.Recv(flags); }
// Receiving functions. public static Msg Recv(SocketBase s, SendRecieveOptions flags) { if (s == null || !s.CheckTag()) { throw new InvalidOperationException(); } Msg msg = RecvMsg(s, flags); if (msg == null) { return null; } // At the moment an oversized message is silently truncated. // TODO: Build in a notification mechanism to report the overflows. //int to_copy = nbytes < len_ ? nbytes : len_; return msg; }
public bool Send(Msg msg, SendRecieveOptions flags) { if (m_ctxTerminated) { ZError.ErrorNumber = (ErrorNumber.ETERM); return false; } // Check whether message passed to the function is valid. if (msg == null) { ZError.ErrorNumber = (ErrorNumber.EFAULT); throw new ArgumentException(); } // Process pending commands, if any. bool rc = ProcessCommands(0, true); if (!rc) return false; // Clear any user-visible flags that are set on the message. msg.ResetFlags(MsgFlags.More); // At this point we impose the flags on the message. if ((flags & SendRecieveOptions.SendMore) > 0) msg.SetFlags(MsgFlags.More); // Try to send the message. rc = XSend(msg, flags); if (rc) return true; if (!ZError.IsError(ErrorNumber.EAGAIN)) return false; // In case of non-blocking send we'll simply propagate // the error - including EAGAIN - up the stack. if ((flags & SendRecieveOptions.DontWait) > 0 || m_options.SendTimeout == 0) return false; // Compute the time when the timeout should occur. // If the timeout is infite, don't care. int timeout = m_options.SendTimeout; long end = timeout < 0 ? 0 : (Clock.NowMs() + timeout); // Oops, we couldn't send the message. Wait for the next // command, process it and try to send the message again. // If timeout is reached in the meantime, return EAGAIN. while (true) { if (!ProcessCommands(timeout, false)) return false; rc = XSend(msg, flags); if (rc) break; if (!ZError.IsError(ErrorNumber.EAGAIN)) return false; if (timeout > 0) { timeout = (int)(end - Clock.NowMs()); if (timeout <= 0) { ZError.ErrorNumber = (ErrorNumber.EAGAIN); return false; } } } return true; }
// Send multiple messages. // // If flag bit ZMQ_SNDMORE is set the vector is treated as // a single multi-part message, i.e. the last message has // ZMQ_SNDMORE bit switched off. // public int SendIOv(SocketBase s, byte[][] a, int count, SendRecieveOptions flags) { if (s == null || !s.CheckTag()) { throw new InvalidOperationException(); } int rc = 0; Msg msg; for (int i = 0; i < count; ++i) { msg = new Msg(a[i]); if (i == count - 1) flags = flags & ~SendRecieveOptions.SendMore; rc = SendMsg(s, msg, flags); if (rc < 0) { rc = -1; break; } } return rc; }
protected override bool XSend(Msg msg, SendRecieveOptions flags) { // Overload the XSUB's send. ZError.ErrorNumber = (ErrorNumber.ENOTSUP); return false; }
private Msg xxrecv(SendRecieveOptions flags_) { Msg msg_ = null; // If there is a prefetched message, return it. if (m_prefetched) { msg_ = m_prefetchedMsg ; m_prefetched = false; m_prefetchedMsg = null; return msg_; } // DEALER socket doesn't use identities. We can safely drop it and while (true) { msg_ = m_fq.Recv (); if (msg_ == null) return msg_; if ((msg_.Flags & MsgFlags.Identity) == 0) break; } return msg_; }
protected override bool XSend(Msg msg, SendRecieveOptions flags) { if (m_pipe == null || !m_pipe.Write (msg)) { ZError.ErrorNumber = (ErrorNumber.EAGAIN); return false; } if ((flags & SendRecieveOptions.SendMore) == 0) m_pipe.Flush (); // Detach the original message from the data buffer. return true; }
protected override bool XSend(Msg msg, SendRecieveOptions flags) { return lb.Send (msg, flags); }
private static int SendMsg(SocketBase s, Msg msg, SendRecieveOptions flags) { int sz = MsgSize(msg); bool rc = s.Send(msg, flags); if (!rc) return -1; return sz; }
protected override bool XSend(Msg msg, SendRecieveOptions flags) { // If we've sent a request and we still haven't got the reply, // we can't send another request. if (m_receivingReply) { throw new InvalidOperationException("Cannot send another request"); } bool rc; // First part of the request is the request identity. if (m_messageBegins) { Msg bottom = new Msg(); bottom.SetFlags (MsgFlags.More); rc = base.XSend (bottom, 0); if (!rc) return false; m_messageBegins = false; } bool more = msg.HasMore; rc = base.XSend (msg, flags); if (!rc) return rc; // If the request was fully sent, flip the FSM into reply-receiving state. if (!more) { m_receivingReply = true; m_messageBegins = true; } return true; }
protected override Msg XRecv(SendRecieveOptions flags) { return xxrecv(flags); }
public void Send(Msg msg, SendRecieveOptions flags) { if (m_ctxTerminated) { throw TerminatingException.Create(); } // Check whether message passed to the function is valid. if (msg == null) { throw NetMQException.Create(ErrorCode.EFAULT); } // Process pending commands, if any. ProcessCommands(0, true); // Clear any user-visible flags that are set on the message. msg.ResetFlags(MsgFlags.More); // At this point we impose the flags on the message. if ((flags & SendRecieveOptions.SendMore) > 0) msg.SetFlags(MsgFlags.More); // Try to send the message. try { XSend(msg, flags); return; } catch (AgainException) { } // In case of non-blocking send we'll simply propagate // the error - including EAGAIN - up the stack. if ((flags & SendRecieveOptions.DontWait) > 0 || m_options.SendTimeout == 0) throw AgainException.Create(); // Compute the time when the timeout should occur. // If the timeout is infite, don't care. int timeout = m_options.SendTimeout; long end = timeout < 0 ? 0 : (Clock.NowMs() + timeout); // Oops, we couldn't send the message. Wait for the next // command, process it and try to send the message again. // If timeout is reached in the meantime, return EAGAIN. while (true) { ProcessCommands(timeout, false); try { XSend(msg, flags); break; } catch (AgainException) { } if (timeout > 0) { timeout = (int)(end - Clock.NowMs()); if (timeout <= 0) { throw AgainException.Create(); } } } }
protected override void XSend(Msg msg, SendRecieveOptions flags) { // Overload the XSUB's send. throw NetMQException.Create("Send not supported on sub socket", ErrorCode.ENOTSUP); }
protected override Msg XRecv(SendRecieveOptions flags) { // Messages cannot be received from PUB socket. ZError.ErrorNumber = (ErrorNumber.ENOTSUP); return null; }
protected override bool XSend(Msg msg, SendRecieveOptions flags) { // If this is the first part of the message it's the ID of the // peer to send the message to. if (!m_moreOut) { Debug.Assert(m_currentOut == null); // If we have malformed message (prefix with no subsequent message) // then just silently ignore it. // TODO: The connections should be killed instead. if (msg.HasMore) { m_moreOut = true; // Find the pipe associated with the identity stored in the prefix. // If there's no such pipe just silently ignore the message, unless // mandatory is set. Blob identity = new Blob(msg.Data); Outpipe op = m_outpipes[identity]; if (op != null) { m_currentOut = op.Pipe; if (!m_currentOut.CheckWrite ()) { op.Active = false; m_currentOut = null; } } else if (m_mandatory) { m_moreOut = false; ZError.ErrorNumber = (ErrorNumber.EHOSTUNREACH); return false; } } return true; } // Check whether this is the last part of the message. m_moreOut = msg.HasMore; // Push the message into the pipe. If there's no out pipe, just drop it. if (m_currentOut != null) { bool ok = m_currentOut.Write (msg); if (!ok) m_currentOut = null; else if (!m_moreOut) { m_currentOut.Flush (); m_currentOut = null; } } else { } // Detach the message from the data buffer. return true; }
protected virtual Msg XRecv(SendRecieveOptions flags) { throw new NotSupportedException("Must Override"); }