/// <summary> /// Bluetooth connection constructor /// </summary> private BluetoothConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, BluetoothClient btClient) : base(connectionInfo, defaultSendReceiveOptions) { if (btClient != null) this.btClient = btClient; dataBuffer = new byte[NetworkComms.InitialReceiveBufferSizeBytes]; }
/// <summary> /// Create a new instance of a UDP listener /// </summary> /// <param name="sendReceiveOptions">The SendReceiveOptions to use with incoming data on this listener</param> /// <param name="applicationLayerProtocol">If enabled NetworkComms.Net uses a custom /// application layer protocol to provide useful features such as inline serialisation, /// transparent packet transmission, remote peer handshake and information etc. We strongly /// recommend you enable the NetworkComms.Net application layer protocol.</param> /// <param name="udpOptions">The UDPOptions to use with this listener</param> /// <param name="allowDiscoverable">Determines if the newly created <see cref="ConnectionListenerBase"/> will be discoverable if <see cref="Tools.PeerDiscovery"/> is enabled.</param> public UDPConnectionListener(SendReceiveOptions sendReceiveOptions, ApplicationLayerProtocolStatus applicationLayerProtocol, UDPOptions udpOptions, bool allowDiscoverable = false) :base(ConnectionType.UDP, sendReceiveOptions, applicationLayerProtocol, allowDiscoverable) { if (applicationLayerProtocol == ApplicationLayerProtocolStatus.Disabled && udpOptions != UDPOptions.None) throw new ArgumentException("If the application layer protocol has been disabled the provided UDPOptions can only be UDPOptions.None."); UDPOptions = udpOptions; }
public void Receive(ref Msg msg, SendReceiveOptions options) { LastOptions = options; byte[] bytes = m_frames.Dequeue(); msg.InitGC(bytes, bytes.Length); if (m_frames.Count != 0) msg.SetFlags(MsgFlags.More); }
/// <summary> /// Create a TCP connection with the provided connectionInfo and sets the connection default SendReceiveOptions. If there is an existing connection that is returned instead. /// If a new connection is created it will be registered with NetworkComms and can be retrieved using <see cref="NetworkComms.GetExistingConnection(ConnectionInfo)"/> and overrides. /// </summary> /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param> /// <param name="defaultSendReceiveOptions">The SendReceiveOptions which will be set as this connections defaults</param> /// <param name="establishIfRequired">If true will establish the TCP connection with the remote end point before returning</param> /// <returns>Returns a <see cref="TCPConnection"/></returns> public static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, bool establishIfRequired = true) { //Added conditional compilation so that GetConnection method usage is not ambiguous. #if WINDOWS_PHONE || NETFX_CORE StreamSocket socket = null; return GetConnection(connectionInfo, defaultSendReceiveOptions, socket, establishIfRequired); #else TcpClient tcpClient = null; return GetConnection(connectionInfo, defaultSendReceiveOptions, tcpClient, establishIfRequired); #endif }
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; }
public static void Send([NotNull] this IOutgoingSocket socket, [NotNull] byte[] data, int length, SendReceiveOptions options) { var msg = new Msg(); msg.InitPool(length); Buffer.BlockCopy(data, 0, msg.Data, 0, length); socket.Send(ref msg, options); msg.Close(); }
/// <summary> /// Create a new connection object /// </summary> /// <param name="connectionInfo">ConnectionInfo corresponding to the new connection</param> /// <param name="defaultSendReceiveOptions">The SendReceiveOptions which should be used as connection defaults</param> protected Connection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions) { //If the application layer protocol is disabled the serialiser must be NullSerializer //and no data processors are allowed. if (connectionInfo.ApplicationLayerProtocol == ApplicationLayerProtocolStatus.Disabled) { if (defaultSendReceiveOptions.Options.ContainsKey("ReceiveConfirmationRequired")) throw new ArgumentException("Attempted to create an unmanaged connection when the provided send receive" + " options specified the ReceiveConfirmationRequired option. Please provide compatible send receive options in order to successfully" + " instantiate this unmanaged connection.", "defaultSendReceiveOptions"); if (defaultSendReceiveOptions.DataSerializer != DPSManager.GetDataSerializer<NullSerializer>()) throw new ArgumentException("Attempted to create an unmanaged connection when the provided send receive" + " options serialiser was not NullSerializer. Please provide compatible send receive options in order to successfully" + " instantiate this unmanaged connection.", "defaultSendReceiveOptions"); if (defaultSendReceiveOptions.DataProcessors.Count > 0) throw new ArgumentException("Attempted to create an unmanaged connection when the provided send receive" + " options contains data processors. Data processors may not be used with unmanaged connections." + " Please provide compatible send receive options in order to successfully instantiate this unmanaged connection.", "defaultSendReceiveOptions"); } SendTimesMSPerKBCache = new CommsMath(); packetBuilder = new PacketBuilder(); //Initialise the sequence counter using the global value //Subsequent values on this connection are guaranteed to be sequential packetSequenceCounter = Interlocked.Increment(ref NetworkComms.totalPacketSendCount); ConnectionInfo = connectionInfo; if (defaultSendReceiveOptions != null) ConnectionDefaultSendReceiveOptions = defaultSendReceiveOptions; else ConnectionDefaultSendReceiveOptions = NetworkComms.DefaultSendReceiveOptions; //Add any listener specific packet handlers if required if (connectionInfo.ConnectionListener != null) connectionInfo.ConnectionListener.AddListenerPacketHandlersToConnection(this); if (NetworkComms.commsShutdown) throw new ConnectionSetupException("Attempting to create new connection after global NetworkComms.Net shutdown has been initiated."); if (ConnectionInfo.ConnectionType == ConnectionType.Undefined || ConnectionInfo.RemoteEndPoint == null) throw new ConnectionSetupException("ConnectionType and RemoteEndPoint must be defined within provided ConnectionInfo."); //If a connection already exists with this info then we can throw an exception here to prevent duplicates if (NetworkComms.ConnectionExists(connectionInfo.RemoteEndPoint, connectionInfo.LocalEndPoint, connectionInfo.ConnectionType, connectionInfo.ApplicationLayerProtocol)) throw new ConnectionSetupException("A " + connectionInfo.ConnectionType.ToString() + " connection already exists with info " + connectionInfo); //We add a reference in the constructor to ensure any duplicate connection problems are picked up here NetworkComms.AddConnectionReferenceByRemoteEndPoint(this); }
/// <summary> /// Initialise a new PriorityQueueItem /// </summary> /// <param name="priority"></param> /// <param name="connection"></param> /// <param name="packetHeader"></param> /// <param name="dataStream"></param> /// <param name="sendReceiveOptions"></param> public PriorityQueueItem(QueueItemPriority priority, Connection connection, PacketHeader packetHeader, MemoryStream dataStream, SendReceiveOptions sendReceiveOptions) { if (connection == null) throw new ArgumentNullException("connection", "Provided Connection parameter cannot be null."); if (packetHeader == null) throw new ArgumentNullException("packetHeader", "Provided PacketHeader parameter cannot be null."); if (dataStream == null) throw new ArgumentNullException("dataStream", "Provided MemoryStream parameter cannot be null."); if (sendReceiveOptions == null) throw new ArgumentNullException("sendReceiveOptions", "Provided sendReceiveOptions cannot be null."); this.Priority = priority; this.Connection = connection; this.PacketHeader = packetHeader; this.DataStream = dataStream; this.SendReceiveOptions = sendReceiveOptions; }
/// <summary> /// Internal <see cref="BluetoothConnection"/> creation which hides the necessary internal calls /// </summary> /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param> /// <param name="defaultSendReceiveOptions">Connection default SendReceiveOptions</param> /// <param name="btClient">If this is an incoming connection we will already have access to the btClient, otherwise use null</param> /// <param name="establishIfRequired">Establish during create if true</param> /// <returns>An existing connection or a new one</returns> internal static BluetoothConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, BluetoothClient btClient, bool establishIfRequired = true) { connectionInfo.ConnectionType = ConnectionType.Bluetooth; //If we have a tcpClient at this stage we must be server side if (btClient != null) connectionInfo.ServerSide = true; bool newConnection = false; BluetoothConnection connection; lock (NetworkComms.globalDictAndDelegateLocker) { List<Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteEndPoint, connectionInfo.LocalEndPoint, connectionInfo.ConnectionType, connectionInfo.ApplicationLayerProtocol); //Check to see if a connection already exists, if it does return that connection, if not return a new one if (existingConnections.Count > 0) { if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace("Attempted to create new BluetoothConnection to connectionInfo='" + connectionInfo + "' but there is an existing connection. Existing connection will be returned instead."); establishIfRequired = false; connection = (BluetoothConnection)existingConnections[0]; } else { if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace("Creating new BluetoothConnection to connectionInfo='" + connectionInfo + "'." + (establishIfRequired ? " Connection will be established." : " Connection will not be established.")); if (connectionInfo.ConnectionState == ConnectionState.Establishing) throw new ConnectionSetupException("Connection state for connection " + connectionInfo + " is marked as establishing. This should only be the case here due to a bug."); //If an existing connection does not exist but the info we are using suggests it should we need to reset the info //so that it can be reused correctly. This case generally happens when using NetworkComms.Net in the format //TCPConnection.GetConnection(info).SendObject(packetType, objToSend); if (connectionInfo.ConnectionState == ConnectionState.Established || connectionInfo.ConnectionState == ConnectionState.Shutdown) connectionInfo.ResetConnectionInfo(); //We add a reference to networkComms for this connection within the constructor connection = new BluetoothConnection(connectionInfo, defaultSendReceiveOptions, btClient); newConnection = true; } } if (newConnection && establishIfRequired) connection.EstablishConnection(); else if (!newConnection) connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS); if (!NetworkComms.commsShutdown) TriggerConnectionKeepAliveThread(); return connection; }
public static byte[] Receive([NotNull] this IReceivingSocket socket, SendReceiveOptions options, out bool hasMore) { var msg = new Msg(); msg.InitEmpty(); socket.Receive(ref msg, options); var data = msg.CloneData(); hasMore = msg.HasMore; msg.Close(); return data; }
/// <summary> /// Transmit a string-message of data over this socket. The string will be encoded into bytes using the specified Encoding. /// </summary> /// <param name="socket">the IOutgoingSocket to transmit on</param> /// <param name="message">a string containing the message to send</param> /// <param name="encoding">the Encoding to use when converting the message-string into bytes</param> /// <param name="options">use this to specify which of the DontWait and SendMore flags to set</param> public static void Send([NotNull] this IOutgoingSocket socket, [NotNull] string message, [NotNull] Encoding encoding, SendReceiveOptions options) { var msg = new Msg(); // Count the number of bytes required to encode the string. // Note that non-ASCII strings may not have an equal number of characters // and bytes. The encoding must be queried for this answer. // With this number, request a buffer from the pool. msg.InitPool(encoding.GetByteCount(message)); // Encode the string into the buffer encoding.GetBytes(message, 0, message.Length, msg.Data, 0); socket.Send(ref msg, options); msg.Close(); }
private TCPConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, TcpClient tcpClient, SSLOptions sslOptions) #endif : base(connectionInfo, defaultSendReceiveOptions) { if (connectionInfo.ConnectionType != ConnectionType.TCP) throw new ArgumentException("Provided connectionType must be TCP.", "connectionInfo"); dataBuffer = new byte[NetworkComms.InitialReceiveBufferSizeBytes]; //We don't guarantee that the tcpClient has been created yet #if WINDOWS_PHONE || NETFX_CORE if (socket != null) this.socket = socket; #else if (tcpClient != null) this.tcpClient = tcpClient; this.SSLOptions = sslOptions; #endif }
// Sending functions. public static void Send(SocketBase s, String str, SendReceiveOptions flags) { byte[] data = Encoding.ASCII.GetBytes(str); Send(s, data, data.Length, flags); }
public static void Send(SocketBase s, Msg msg, SendReceiveOptions flags) { SendMsg(s, msg, flags); }
public override void Receive(ref Msg msg, SendReceiveOptions options) { throw new NotSupportedException("PublisherSocket doesn't support receiving"); }
/// <summary> /// Internal <see cref="TCPConnection"/> creation which hides the necessary internal calls /// </summary> /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param> /// <param name="defaultSendReceiveOptions">Connection default SendReceiveOptions</param> /// <param name="tcpClient">If this is an incoming connection we will already have access to the tcpClient, otherwise use null</param> /// <param name="establishIfRequired">Establish during create if true</param> /// <param name="sslOptions">SSL options that will be used with this connection.</param> /// <returns>An existing connection or a new one</returns> internal static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, TcpClient tcpClient, bool establishIfRequired, SSLOptions sslOptions = null) #endif { connectionInfo.ConnectionType = ConnectionType.TCP; //If we have a tcpClient at this stage we must be server side #if WINDOWS_PHONE || NETFX_CORE if (socket != null) { connectionInfo.ServerSide = true; } #else if (tcpClient != null) { connectionInfo.ServerSide = true; } if (sslOptions == null) { sslOptions = new SSLOptions(); } #endif //Set default connection options if none have been provided if (defaultSendReceiveOptions == null) { defaultSendReceiveOptions = NetworkComms.DefaultSendReceiveOptions; } bool newConnection = false; TCPConnection connection; lock (NetworkComms.globalDictAndDelegateLocker) { List <Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteIPEndPoint, connectionInfo.LocalIPEndPoint, connectionInfo.ConnectionType, connectionInfo.ApplicationLayerProtocol); //Check to see if a connection already exists, if it does return that connection, if not return a new one if (existingConnections.Count > 0) { if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Trace("Attempted to create new TCPConnection to connectionInfo='" + connectionInfo + "' but there is an existing connection. Existing connection will be returned instead."); } establishIfRequired = false; connection = (TCPConnection)existingConnections[0]; } else { if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Trace("Creating new TCPConnection to connectionInfo='" + connectionInfo + "'." + (establishIfRequired ? " Connection will be established." : " Connection will not be established.")); } if (connectionInfo.ConnectionState == ConnectionState.Establishing) { throw new ConnectionSetupException("Connection state for connection " + connectionInfo + " is marked as establishing. This should only be the case here due to a bug."); } //If an existing connection does not exist but the info we are using suggests it should we need to reset the info //so that it can be reused correctly. This case generally happens when using Comms in the format //TCPConnection.GetConnection(info).SendObject(packetType, objToSend); if (connectionInfo.ConnectionState == ConnectionState.Established || connectionInfo.ConnectionState == ConnectionState.Shutdown) { connectionInfo.ResetConnectionInfo(); } //We add a reference to networkComms for this connection within the constructor #if WINDOWS_PHONE || NETFX_CORE connection = new TCPConnection(connectionInfo, defaultSendReceiveOptions, socket); #else connection = new TCPConnection(connectionInfo, defaultSendReceiveOptions, tcpClient, sslOptions); #endif newConnection = true; } } if (newConnection && establishIfRequired) { connection.EstablishConnection(); } else if (!newConnection) { connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS); } if (!NetworkComms.commsShutdown) { TriggerConnectionKeepAliveThread(); } return(connection); }
public override void Send(byte[] data, int length, SendReceiveOptions options) { throw new NotSupportedException("Subscriber socket doesn't support sending"); }
protected override bool XSend(ref Msg msg, SendReceiveOptions 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. byte[] identity = msg.Data; if (msg.Size != msg.Data.Length) { identity = new byte[msg.Size]; Buffer.BlockCopy(msg.Data, 0, identity, 0, msg.Size); } Outpipe op; if (m_outpipes.TryGetValue(identity, out op)) { m_currentOut = op.Pipe; if (!m_currentOut.CheckWrite()) { op.Active = false; m_currentOut = null; if (m_mandatory) { m_moreOut = false; return(false); } } } else if (m_mandatory) { m_moreOut = false; throw new HostUnreachableException(); } } // Detach the message from the data buffer. msg.Close(); msg.InitEmpty(); return(true); } if (m_options.RawSocket) { msg.ResetFlags(MsgFlags.More); } // 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) { // Close the remote connection if user has asked to do so // by sending zero length message. // Pending messages in the pipe will be dropped (on receiving term- ack) if (m_rawSocket && msg.Size == 0) { m_currentOut.Terminate(false); msg.Close(); msg.InitEmpty(); m_currentOut = null; return(true); } bool ok = m_currentOut.Write(ref msg); if (!ok) { m_currentOut = null; } else if (!m_moreOut) { m_currentOut.Flush(); m_currentOut = null; } } else { msg.Close(); } // Detach the message from the data buffer. msg.InitEmpty(); return(true); }
public static string ReceiveString([NotNull] this IReceivingSocket socket, [NotNull] Encoding encoding, SendReceiveOptions options) { bool hasMore; return socket.ReceiveString(encoding, options, out hasMore); }
// 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); } }
public static string ReceiveString([NotNull] this IReceivingSocket socket, [NotNull] Encoding encoding, SendReceiveOptions options, out bool hasMore) { if (encoding == null) throw new ArgumentNullException("encoding"); var msg = new Msg(); msg.InitEmpty(); socket.Receive(ref msg, options); hasMore = msg.HasMore; string data = msg.Size > 0 ? encoding.GetString(msg.Data, msg.Offset, msg.Size) : string.Empty; msg.Close(); return data; }
/// <summary> /// Initialise a new PacketTypeUnwrapper /// </summary> /// <param name="packetTypeStr">The packet type of this unwrapper</param> /// <param name="options">The SendReceiveOptions to use with this unwrapper</param> public PacketTypeUnwrapper(string packetTypeStr, SendReceiveOptions options) { this.packetTypeStr = packetTypeStr; this.Options = options; }
protected override bool XRecv(SendReceiveOptions flags, ref Msg msg) { if (m_prefetched) { if (!m_identitySent) { msg.Move(ref m_prefetchedId); m_identitySent = true; } else { msg.Move(ref m_prefetchedMsg); m_prefetched = false; } m_moreIn = msg.HasMore; return(true); } Pipe[] pipe = new Pipe[1]; bool isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg); // 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. while (isMessageAvailable && msg.IsIdentity) { isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg); } if (!isMessageAvailable) { return(false); } 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.Move(ref msg); m_prefetched = true; byte[] identity = pipe[0].Identity; msg.InitPool(identity.Length); msg.Put(identity, 0, identity.Length); msg.SetFlags(MsgFlags.More); m_identitySent = true; } return(true); }
/// <summary> /// Create a TCP connection with the provided connectionInfo and sets the connection default SendReceiveOptions. If there is an existing connection that is returned instead. /// If a new connection is created it will be registered with NetworkComms and can be retrieved using <see cref="NetworkComms.GetExistingConnection(ConnectionInfo)"/> and overrides. /// </summary> /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param> /// <param name="defaultSendReceiveOptions">The SendReceiveOptions which will be set as this connections defaults</param> /// <param name="sslOptions">SSLOptions to use with this connection</param> /// <param name="establishIfRequired">If true will establish the TCP connection with the remote end point before returning</param> /// <returns>Returns a <see cref="TCPConnection"/></returns> public static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, SSLOptions sslOptions, bool establishIfRequired = true) { return(GetConnection(connectionInfo, defaultSendReceiveOptions, null, establishIfRequired, sslOptions)); }
/// <summary> /// Internal <see cref="TCPConnection"/> creation which hides the necessary internal calls /// </summary> /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param> /// <param name="defaultSendReceiveOptions">Connection default SendReceiveOptions</param> /// <param name="socket">If this is an incoming connection we will already have access to the socket, otherwise use null</param> /// <param name="establishIfRequired">Establish during create if true</param> /// <returns>An existing connection or a new one</returns> internal static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, StreamSocket socket, bool establishIfRequired)
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); }
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; }
// 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, SendReceiveOptions flags) { if (s == null || !s.CheckTag()) { throw NetMQException.Create(ErrorCode.EFAULT); } 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; }
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; }
private static void SendMsg(SocketBase s, Msg msg, SendReceiveOptions flags) { s.Send(msg, flags); }
public override void Send(ref Msg msg, SendReceiveOptions options) { throw new NotSupportedException("Subscriber socket doesn't support sending"); }
protected internal override Msg ReceiveInternal(SendReceiveOptions options, out bool hasMore) { throw new NotSupportedException("Push socket doesn't support receiving"); }
// Receiving functions. public static Msg Recv(SocketBase s, SendReceiveOptions flags) { if (s == null || !s.CheckTag()) { throw NetMQException.Create(ErrorCode.EFAULT); } 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; }
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 static Msg RecvMsg(SocketBase s, SendReceiveOptions flags) { return s.Recv(flags); }
public static string ReceiveString([NotNull] this IReceivingSocket socket, SendReceiveOptions options, out bool hasMore) { return socket.ReceiveString(Encoding.ASCII, options, out hasMore); }
public static void Send(this IOutgoingSocket socket, byte[] data, int length, SendReceiveOptions options) { var msg = new Msg(); msg.InitPool(length); Buffer.BlockCopy(data, 0, msg.Data, 0, length); socket.Send(ref msg, options); msg.Close(); }