static int Main(string[] args) { if (args.Length != 3) { Console.WriteLine("usage: remote_thr <connect-to> <message-size> <message-count>"); return 1; } string connectTo = args[0]; int messageSize = int.Parse(args[1]); int messageCount = int.Parse(args[2]); var context = ZMQ.CtxNew(); var pushSocket = ZMQ.Socket(context, ZmqSocketType.Push); pushSocket.Connect(connectTo); for (int i = 0; i != messageCount; i++) { var message = new Msg(messageSize); pushSocket.Send(message, SendReceiveOptions.None); } pushSocket.Close(); context.Terminate(); return 0; }
protected override bool XSetSocketOption(ZmqSocketOptions option, Object optval) { if (option != ZmqSocketOptions.Subscribe && option != ZmqSocketOptions.Unsubscribe) { ZError.ErrorNumber = (ErrorNumber.EINVAL); return false; } byte[] val; if (optval is String) val = Encoding.ASCII.GetBytes ((String)optval); else if (optval is byte[]) val = (byte[]) optval; else throw new ArgumentException(); // Create the subscription message. Msg msg = new Msg(val.Length + 1); if (option == ZmqSocketOptions.Subscribe) msg.Put((byte)1); else if (option == ZmqSocketOptions.Unsubscribe) msg.Put((byte)0); msg.Put (val,1); // Pass it further on in the stack. bool rc = base.XSend (msg, 0); return rc; }
bool RawMessageReady() { // Destroy content of the old message. m_inProgress = null; // Read new message. If there is none, return false. // Note that new state is set only if write is successful. That way // unsuccessful write will cause retry on the next state machine // invocation. if (m_msgSource == null) { return false; } m_inProgress = m_msgSource.PullMsg(); if (m_inProgress == null) return false; m_inProgress.ResetFlags(MsgFlags.Shared | MsgFlags.More | MsgFlags.Identity); NextStep(null, 0, RawMessageSizeReadyState, true); return true; }
protected override void XSetSocketOption(ZmqSocketOptions option, Object optval) { if (option != ZmqSocketOptions.Subscribe && option != ZmqSocketOptions.Unsubscribe) { throw InvalidException.Create(); } byte[] val; if (optval is String) val = Encoding.ASCII.GetBytes ((String)optval); else if (optval is byte[]) val = (byte[]) optval; else throw InvalidException.Create(); // Create the subscription message. Msg msg = new Msg(val.Length + 1); if (option == ZmqSocketOptions.Subscribe) msg.Put((byte)1); else if (option == ZmqSocketOptions.Unsubscribe) msg.Put((byte)0); msg.Put (val,1); // Pass it further on in the stack. base.XSend (msg, 0); }
public override bool MessageReadySize(int msgSize) { m_inProgress = new Msg(msgSize); NextStep(m_inProgress.Data, m_inProgress.Size, RawMessageReadyState); return true; }
static int Main(string[] args) { if (args.Length != 3) { Console.WriteLine("usage: remote_lat remote_lat <connect-to> <message-size> <roundtrip-count>"); return 1; } string connectTo = args[0]; int messageSize = int.Parse(args[1]); int roundtripCount = int.Parse(args[2]); var context = ZMQ.CtxNew(); var reqSocket = ZMQ.Socket(context, ZmqSocketType.Req); bool connected = reqSocket.Connect(connectTo); if (!connected) { Console.WriteLine("error in zmq_connect"); } var message = new Msg(messageSize); var stopWatch = Stopwatch.StartNew(); for (int i = 0; i != roundtripCount; i++) { bool sent = reqSocket.Send(message, SendRecieveOptions.None); if (!sent) { Console.WriteLine("error in zmq_sendmsg"); return -1; } message = reqSocket.Recv(SendRecieveOptions.None); if (message.Size != messageSize) { Console.WriteLine("message of incorrect size received. Received: " + message.Size + " Expected: " + messageSize); return -1; } } stopWatch.Stop(); message.Close(); double elapsedMicroseconds = stopWatch.ElapsedTicks * 1000000 / Stopwatch.Frequency; double latency = elapsedMicroseconds / (roundtripCount * 2); Console.WriteLine("message size: {0} [B]", messageSize); Console.WriteLine("roundtrip count: {0}", roundtripCount); Console.WriteLine("average latency: {0:0.000} [µs]", latency); reqSocket.Close(); context.Terminate(); return 0; }
protected override bool XRecv(SendReceiveOptions flags, out Msg msg) { // Deallocate old content of the message. msg = null; if (m_pipe == null || (msg = m_pipe.Read ()) == null) { return false; } return true; }
protected override bool XHasIn() { // We may already have a message pre-fetched. if (m_prefetched) return true; // Try to read the next message to the pre-fetch buffer. m_prefetchedMsg = xxrecv(SendRecieveOptions.DontWait); if (m_prefetchedMsg == null && ZError.IsError(ErrorNumber.EAGAIN)) return false; m_prefetched = true; return true; }
protected override bool XHasIn() { // We may already have a message pre-fetched. if (m_prefetched) return true; // Try to read the next message to the pre-fetch buffer. try { m_prefetchedMsg = xxrecv(SendRecieveOptions.DontWait); } catch (AgainException ex) { return false; } m_prefetched = true; return true; }
public Stream(Ctx parent, int threadId, int sid) : base(parent, threadId, sid) { m_prefetched = false; m_identitySent = false; m_currentOut = null; m_moreOut = false; m_nextPeerId = Utils.GenerateRandom(); m_options.SocketType = ZmqSocketType.Stream; m_fq = new FQ(); m_prefetchedId = new Msg(); m_prefetchedMsg = new Msg(); m_outpipes = new Dictionary<Blob, Outpipe>(); m_options.RawSocket = true; }
static XSub() { s_sendSubscription = (data, size, arg) => { Pipe pipe = (Pipe) arg; // Create the subsctription message. Msg msg = new Msg(size + 1); msg.Put((byte)1); msg.Put(data,1, size); // Send it to the pipe. bool sent = pipe.Write (msg); // If we reached the SNDHWM, and thus cannot send the subscription, drop // the subscription message instead. This matches the behaviour of // zmq_setsockopt(ZMQ_SUBSCRIBE, ...), which also drops subscriptions // when the SNDHWM is reached. if (!sent) msg.Close (); }; }
public static void Send(SocketBase s, byte[] buf, int len, SendReceiveOptions flags) { if (s == null || !s.CheckTag()) { throw NetMQException.Create(ErrorCode.EFAULT); } Msg msg = new Msg(len); msg.Put(buf, 0, len); SendMsg(s, msg, flags); }
public static void Send(SocketBase s, Msg msg, SendReceiveOptions flags) { SendMsg(s, msg, flags); }
public static int MsgSize(Msg msg) { return msg.Size; }
public static int MsgGet(Msg msg) { return ZmqMsgGet(msg, MsgFlags.More); }
protected override bool XRecv(SendReceiveOptions flags, out Msg msg) { bool isMessageAvailable; // 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) { isMessageAvailable = base.XRecv (flags, out msg); if (!isMessageAvailable) { return false; } else if (msg == null) { return true; } if (msg.HasMore) { // Empty message part delimits the traceback stack. bool bottom = (msg.Size == 0); // Push it to the reply pipe. isMessageAvailable = base.XSend(msg, flags); if(!isMessageAvailable) { return false; } 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. isMessageAvailable = base.XRecv(flags, out msg); if (!isMessageAvailable) { return false; } else if (msg == null) { return true; } // If whole request is read, flip the FSM to reply-sending state. if (!msg.HasMore) { m_sendingReply = true; m_requestBegins = true; } return true; }
protected override bool XRecv(SendReceiveOptions flags, out Msg msg) { bool isMessageAvailable; 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) { isMessageAvailable = base.XRecv(flags, out msg); if (!isMessageAvailable) { return false; } else if (msg == null) { return true; } // TODO: This should also close the connection with the peer! if (!msg.HasMore || msg.Size != 0) { while (true) { isMessageAvailable = base.XRecv(flags, out msg); Debug.Assert(msg != null); if (!msg.HasMore) break; } msg = null; return false; } m_messageBegins = false; } isMessageAvailable = base.XRecv(flags, out msg); if (!isMessageAvailable) { return false; } else if (msg == null) { return true; } // If the reply is fully received, flip the FSM into request-sending state. if (!msg.HasMore) { m_receivingReply = false; m_messageBegins = true; } return true; }
private static void SendMsg(SocketBase s, Msg msg, SendReceiveOptions flags) { s.Send(msg, flags); }
public static bool CreateProxy(SocketBase frontend, SocketBase backend, SocketBase capture) { // The algorithm below assumes ratio of requests and replies processed // under full load to be 1:1. int more; int rc; Msg msg; PollItem[] items = new PollItem[2]; items[0] = new PollItem(frontend, PollEvents.PollIn); items[1] = new PollItem(backend, PollEvents.PollIn); while (true) { // Wait while there are either requests or replies to process. rc = ZMQ.Poll(items, -1); if (rc < 0) return false; // Process a request. if ((items[0].ResultEvent & PollEvents.PollIn) == PollEvents.PollIn) { while (true) { try { msg = frontend.Recv(0); } catch (TerminatingException) { return false; } if (msg == null) { return false; } more = frontend.GetSocketOption(ZmqSocketOptions.ReceiveMore); if (more < 0) return false; // Copy message to capture socket if any if (capture != null) { Msg ctrl = new Msg(msg); capture.Send(ctrl, more > 0 ? SendReceiveOptions.SendMore : 0); } backend.Send(msg, more > 0 ? SendReceiveOptions.SendMore : 0); if (more == 0) break; } } // Process a reply. if ((items[1].ResultEvent & PollEvents.PollIn) == PollEvents.PollIn) { while (true) { try { msg = backend.Recv(0); } catch (TerminatingException) { return false; } if (msg == null) { return false; } more = backend.GetSocketOption(ZmqSocketOptions.ReceiveMore); if (more < 0) return false; // Copy message to capture socket if any if (capture != null) { Msg ctrl = new Msg(msg); capture.Send(ctrl, more > 0 ? SendReceiveOptions.SendMore : 0); } frontend.Send(msg, more > 0 ? SendReceiveOptions.SendMore : 0); if (more == 0) break; } } } }
public void Put(Msg data, int i) { Put(data.m_data, i); }
private bool OneByteSizeReady() { m_tmpbuf.Reset(); // First byte of size is read. If it is 0xff read 8-byte size. // Otherwise allocate the buffer for message data and read the // message data into it. byte first = m_tmpbuf[0]; if (first == 0xff) { NextStep (m_tmpbuf, 8, EightByteSizeReadyState); } else { // There has to be at least one byte (the flags) in the message). if (first == 0) { DecodingError (); return false; } // in_progress is initialised at this point so in theory we should // close it before calling zmq_msg_init_size, however, it's a 0-byte // message and thus we can treat it as uninitialised... if (m_maxmsgsize >= 0 && (long) (first -1) > m_maxmsgsize) { DecodingError (); return false; } else { m_inProgress = new Msg(first-1); } NextStep (m_tmpbuf,1, FlagsReadyState); } return true; }
private bool EightByteSizeReady() { m_tmpbuf.Reset(); // 8-byte payload length is read. Allocate the buffer // for message body and read the message data into it. long payloadLength = m_tmpbuf.GetLong(0); // There has to be at least one byte (the flags) in the message). if (payloadLength == 0) { DecodingError (); return false; } // Message size must not exceed the maximum allowed size. if (m_maxmsgsize >= 0 && payloadLength - 1 > m_maxmsgsize) { DecodingError (); return false; } // Message size must fit within range of size_t data type. if (payloadLength - 1 > int.MaxValue) { DecodingError (); return false; } int msgSize = (int)(payloadLength - 1); // in_progress is initialized at this point so in theory we should // close it before calling init_size, however, it's a 0-byte // message and thus we can treat it as uninitialized... m_inProgress = new Msg(msgSize); NextStep (m_tmpbuf, 1, FlagsReadyState); return true; }
public static int ZmqMsgGet(Msg msg, MsgFlags option) { switch (option) { case MsgFlags.More: return msg.HasMore ? 1 : 0; default: throw InvalidException.Create(); } }
public bool PushMsg(Msg msg) { Debug.Assert(m_options.SocketType == ZmqSocketType.Pub || m_options.SocketType == ZmqSocketType.Xpub); // The first message is identity. // Let the session process it. bool rc = m_session.PushMsg(msg); Debug.Assert(rc); // Inject the subscription message so that the ZMQ 2.x peer // receives our messages. msg = new Msg(1); msg.Put((byte) 1); rc = m_session.PushMsg(msg); m_session.Flush(); // Once we have injected the subscription message, we can // Divert the message flow back to the session. Debug.Assert(m_decoder != null); m_decoder.SetMsgSink(m_session); return rc; }
// 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 void SendIOv(SocketBase s, byte[][] a, int count, SendReceiveOptions flags) { if (s == null || !s.CheckTag()) { throw NetMQException.Create(ErrorCode.EFAULT); } Msg msg; for (int i = 0; i < count; ++i) { msg = new Msg(a[i]); if (i == count - 1) flags = flags & ~SendReceiveOptions.SendMore; SendMsg(s, msg, flags); } }
protected override bool XSend(Msg msg, SendReceiveOptions 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. bool isMessageSent = base.XSend (msg, flags); if (!isMessageSent) { return false; } // If the reply is complete flip the FSM back to request receiving state. else if (!more) m_sendingReply = false; return true; }
private void Clone(Msg m) { MsgType = m.MsgType; m_flags = m.m_flags; m_size = m.m_size; m_buf = m.m_buf; m_data = m.m_data; }
public override void PushMsg(Msg msg) { switch (m_state) { case State.Bottom: if (msg.Flags == MsgFlags.More && msg.Size == 0) { m_state = State.Body; base.PushMsg(msg); } break; case State.Body: if (msg.Flags == MsgFlags.More) base.PushMsg(msg); if (msg.Flags == 0) { m_state = State.Bottom; base.PushMsg(msg); } break; case State.Identity: if (msg.Flags == 0) { m_state = State.Bottom; base.PushMsg(msg); } break; default: throw NetMQException.Create(ErrorCode.EFAULT); } }
protected override bool XSend(Msg msg, SendReceiveOptions flags) { if (m_pipe == null || !m_pipe.Write (msg)) { return false; } if ((flags & SendReceiveOptions.SendMore) == 0) m_pipe.Flush (); // Detach the original message from the data buffer. return true; }
public Msg(Msg m) { Clone(m); }