예제 #1
0
        public StreamEngine(Socket fd, Options options, String endpoint)
        {
            m_handle = fd;
            //      inbuf = null;
            m_insize     = 0;
            m_inputError = false;
            //        outbuf = null;
            m_outsize     = 0;
            m_handshaking = true;
            m_session     = null;
            m_options     = options;
            m_plugged     = false;
            m_endpoint    = endpoint;
            m_socket      = null;
            m_encoder     = null;
            m_decoder     = null;

            //  Put the socket into non-blocking mode.
            Utils.UnblockSocket(m_handle);

            //  Set the socket buffer limits for the underlying socket.
            if (m_options.SendBuffer != 0)
            {
                m_handle.SendBufferSize = m_options.SendBuffer;
            }
            if (m_options.ReceiveBuffer != 0)
            {
                m_handle.ReceiveBufferSize = m_options.ReceiveBuffer;
            }
        }
예제 #2
0
        public void Plug(IOThread ioThread,
                         SessionBase session)
        {
            Debug.Assert(!m_plugged);
            m_plugged = true;

            //  Connect to session object.
            Debug.Assert(m_session == null);
            Debug.Assert(session != null);
            m_session = session;
            m_socket  = m_session.Socket;

            m_ioObject = new IOObject(null);
            m_ioObject.SetHandler(this);
            //  Connect to I/O threads poller object.
            m_ioObject.Plug(ioThread);
            m_ioObject.AddFd(m_handle);
            m_ioEnabled = true;

            if (m_options.RawSocket)
            {
                m_encoder     = new RawEncoder(Config.OutBatchSize, session, m_options.Endian);
                m_decoder     = new RawDecoder(Config.InBatchSize, m_options.Maxmsgsize, session, m_options.Endian);
                m_handshaking = false;
            }
            else
            {
                //  Send the 'length' and 'flags' fields of the identity message.
                //  The 'length' field is encoded in the long format.

                m_greetingOutputBuffer[m_outsize++] = ((byte)0xff);
                m_greetingOutputBuffer.PutLong(m_options.Endian, (long)m_options.IdentitySize + 1, 1);
                m_outsize += 8;
                m_greetingOutputBuffer[m_outsize++] = ((byte)0x7f);

                m_outpos = new ByteArraySegment(m_greetingOutputBuffer);
            }

            m_ioObject.SetPollin(m_handle);
            m_ioObject.SetPollout(m_handle);

            //  Flush all the data that may have been already received downstream.
            InEvent();
        }
예제 #3
0
        private bool Handshake()
        {
            Debug.Assert(m_handshaking);

            //  Receive the greeting.
            while (m_greetingBytesRead < GreetingSize)
            {
                ByteArraySegment greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);

                int n = Read(greetingSegment, GreetingSize - m_greetingBytesRead);
                if (n == -1)
                {
                    Error();
                    return(false);
                }

                if (n == 0)
                {
                    return(false);
                }

                m_greetingBytesRead += n;

                //  We have received at least one byte from the peer.
                //  If the first byte is not 0xff, we know that the
                //  peer is using unversioned protocol.
                if (m_greeting[0] != 0xff)
                {
                    break;
                }

                if (m_greetingBytesRead < 10)
                {
                    continue;
                }

                //  Inspect the right-most bit of the 10th byte (which coincides
                //  with the 'flags' field if a regular message was sent).
                //  Zero indicates this is a header of identity message
                //  (i.e. the peer is using the unversioned protocol).
                if ((m_greeting[9] & 0x01) == 0)
                {
                    break;
                }

                //  The peer is using versioned protocol.
                //  Send the rest of the greeting, if necessary.
                if (!(((byte[])m_outpos) == ((byte[])m_greetingOutputBuffer) &&
                      m_outpos.Offset + m_outsize == GreetingSize))
                {
                    if (m_outsize == 0)
                    {
                        m_ioObject.SetPollout(m_handle);
                    }

                    m_outpos[m_outsize++] = 1; // Protocol version
                    m_outpos[m_outsize++] = (byte)m_options.SocketType;
                }
            }

            //  Is the peer using the unversioned protocol?
            //  If so, we send and receive rests of identity
            //  messages.
            if (m_greeting[0] != 0xff || (m_greeting[9] & 0x01) == 0)
            {
                m_encoder = new Encoder(Config.OutBatchSize, m_options.Endian);
                m_encoder.SetMsgSource(m_session);

                m_decoder = new Decoder(Config.InBatchSize, m_options.Maxmsgsize, m_options.Endian);

                m_decoder.SetMsgSink(m_session);

                //  We have already sent the message header.
                //  Since there is no way to tell the encoder to
                //  skip the message header, we simply throw that
                //  header data away.
                int              headerSize = m_options.IdentitySize + 1 >= 255 ? 10 : 2;
                byte[]           tmp        = new byte[10];
                ByteArraySegment bufferp    = new ByteArraySegment(tmp);

                int bufferSize = headerSize;

                m_encoder.GetData(ref bufferp, ref bufferSize);

                Debug.Assert(bufferSize == headerSize);

                //  Make sure the decoder sees the data we have already received.
                m_inpos  = new ByteArraySegment(m_greeting);
                m_insize = m_greetingBytesRead;

                //  To allow for interoperability with peers that do not forward
                //  their subscriptions, we inject a phony subsription
                //  message into the incomming message stream. To put this
                //  message right after the identity message, we temporarily
                //  divert the message stream from session to ourselves.
                if (m_options.SocketType == ZmqSocketType.Pub || m_options.SocketType == ZmqSocketType.Xpub)
                {
                    m_decoder.SetMsgSink(this);
                }
            }
            else if (m_greeting[VersionPos] == 0)
            {
                //  ZMTP/1.0 framing.
                m_encoder = new Encoder(Config.OutBatchSize, m_options.Endian);
                m_encoder.SetMsgSource(m_session);

                m_decoder = new Decoder(Config.InBatchSize, m_options.Maxmsgsize, m_options.Endian);
                m_decoder.SetMsgSink(m_session);
            }
            else
            {
                //  v1 framing protocol.
                m_encoder = new V1Encoder(Config.OutBatchSize, m_session, m_options.Endian);

                m_decoder = new V1Decoder(Config.InBatchSize, m_options.Maxmsgsize, m_session, m_options.Endian);
            }
            // Start polling for output if necessary.
            if (m_outsize == 0)
            {
                m_ioObject.SetPollout(m_handle);
            }

            //  Handshaking was successful.
            //  Switch into the normal message flow.
            m_handshaking = false;

            return(true);
        }
예제 #4
0
        public StreamEngine(Socket fd, Options options, String endpoint)
        {
            m_handle = fd;
            //      inbuf = null;
            m_insize = 0;
            m_inputError = false;
            //        outbuf = null;
            m_outsize = 0;
            m_handshaking = true;
            m_session = null;
            m_options = options;
            m_plugged = false;
            m_endpoint = endpoint;
            m_socket = null;
            m_encoder = null;
            m_decoder = null;

            //  Put the socket into non-blocking mode.
            Utils.UnblockSocket(m_handle);

            //  Set the socket buffer limits for the underlying socket.
            if (m_options.SendBuffer != 0)
            {
                m_handle.SendBufferSize = m_options.SendBuffer;
            }
            if (m_options.ReceiveBuffer != 0)
            {
                m_handle.ReceiveBufferSize = m_options.ReceiveBuffer;
            }
        }
예제 #5
0
        private bool Handshake()
        {
            Debug.Assert(m_handshaking);

            //  Receive the greeting.
            while (m_greetingBytesRead < GreetingSize)
            {
                ByteArraySegment greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead);

                int n = Read(greetingSegment, GreetingSize - m_greetingBytesRead);
                if (n == -1)
                {
                    Error();
                    return false;
                }

                if (n == 0)
                    return false;

                m_greetingBytesRead += n;

                //  We have received at least one byte from the peer.
                //  If the first byte is not 0xff, we know that the
                //  peer is using unversioned protocol.
                if (m_greeting[0] != 0xff)
                    break;

                if (m_greetingBytesRead < 10)
                    continue;

                //  Inspect the right-most bit of the 10th byte (which coincides
                //  with the 'flags' field if a regular message was sent).
                //  Zero indicates this is a header of identity message
                //  (i.e. the peer is using the unversioned protocol).
                if ((m_greeting[9] & 0x01) == 0)
                    break;

                //  The peer is using versioned protocol.
                //  Send the rest of the greeting, if necessary.
                if (!(((byte[]) m_outpos) == ((byte[]) m_greetingOutputBuffer) &&
                      m_outpos.Offset + m_outsize == GreetingSize))
                {
                    if (m_outsize == 0)
                        m_ioObject.SetPollout(m_handle);

                    m_outpos[m_outsize++] = 1; // Protocol version
                    m_outpos[m_outsize++] = (byte) m_options.SocketType;
                }
            }

            //  Is the peer using the unversioned protocol?
            //  If so, we send and receive rests of identity
            //  messages.
            if (m_greeting[0] != 0xff || (m_greeting[9] & 0x01) == 0)
            {
                m_encoder = new Encoder(Config.OutBatchSize);
                m_encoder.SetMsgSource(m_session);

                m_decoder = new Decoder(Config.InBatchSize, m_options.Maxmsgsize);

                m_decoder.SetMsgSink(m_session);

                //  We have already sent the message header.
                //  Since there is no way to tell the encoder to
                //  skip the message header, we simply throw that
                //  header data away.
                int headerSize = m_options.IdentitySize + 1 >= 255 ? 10 : 2;
                byte[] tmp = new byte[10];
                ByteArraySegment bufferp = new ByteArraySegment(tmp);

                int bufferSize = headerSize;

                m_encoder.GetData(ref bufferp, ref bufferSize);

                Debug.Assert(bufferSize == headerSize);

                //  Make sure the decoder sees the data we have already received.
                m_inpos = new ByteArraySegment(m_greeting);
                m_insize = m_greetingBytesRead;

                //  To allow for interoperability with peers that do not forward
                //  their subscriptions, we inject a phony subsription
                //  message into the incomming message stream. To put this
                //  message right after the identity message, we temporarily
                //  divert the message stream from session to ourselves.
                if (m_options.SocketType == ZmqSocketType.Pub || m_options.SocketType == ZmqSocketType.Xpub)
                    m_decoder.SetMsgSink(this);
            }
            else if (m_greeting[VersionPos] == 0)
            {
                //  ZMTP/1.0 framing.
                m_encoder = new Encoder(Config.OutBatchSize);
                m_encoder.SetMsgSource(m_session);

                m_decoder = new Decoder(Config.InBatchSize, m_options.Maxmsgsize);
                m_decoder.SetMsgSink(m_session);
            }
            else
            {
                //  v1 framing protocol.
                m_encoder = new V1Encoder(Config.OutBatchSize, m_session);

                m_decoder = new V1Decoder(Config.InBatchSize, m_options.Maxmsgsize, m_session);
            }
            // Start polling for output if necessary.
            if (m_outsize == 0)
                m_ioObject.SetPollout(m_handle);

            //  Handshaking was successful.
            //  Switch into the normal message flow.
            m_handshaking = false;

            return true;
        }
예제 #6
0
        public void Plug(IOThread ioThread,
                     SessionBase session)
        {
            Debug.Assert(!m_plugged);
              m_plugged = true;

              //  Connect to session object.
              Debug.Assert(m_session == null);
              Debug.Assert(session != null);
              m_session = session;
              m_socket = m_session.Socket;

              m_ioObject = new IOObject(null);
              m_ioObject.SetHandler(this);
              //  Connect to I/O threads poller object.
              m_ioObject.Plug(ioThread);
              m_ioObject.AddFd(m_handle);

              if (m_options.RawSocket)
              {
            m_encoder = new RawEncoder(Config.OutBatchSize, session, m_options.Endian);
            m_decoder = new RawDecoder(Config.InBatchSize, m_options.Maxmsgsize, session, m_options.Endian);
            m_handshaking = false;
              }
              else
              {
            //  Send the 'length' and 'flags' fields of the identity message.
            //  The 'length' field is encoded in the long format.

            m_greetingOutputBuffer[m_outsize++] = ((byte)0xff);
            m_greetingOutputBuffer.PutLong(m_options.Endian, (long)m_options.IdentitySize + 1, 1);
            m_outsize += 8;
            m_greetingOutputBuffer[m_outsize++] = ((byte)0x7f);

            m_outpos = new ByteArraySegment(m_greetingOutputBuffer);
              }

              m_ioObject.SetPollin(m_handle);
              m_ioObject.SetPollout(m_handle);

              //  Flush all the data that may have been already received downstream.
              InEvent();
        }