Пример #1
0
        /// <summary>
        /// Begins writing period terminated data to socket. The data is terminated by a line containing only a period, that is,
        /// the character sequence "&lt;CRLF&gt;.&lt;CRLF&gt;". Before sending a line of text, check the first
        /// character of the line.If it is a period, one additional period is inserted at the beginning of the line.
        /// </summary>
        /// <param name="stream">Stream which data to write. Reading begins from stream current position and is readed to EOS.</param>
        /// <param name="closeStream">Specifies if stream is closed after write operation has completed.</param>
        /// <param name="tag">User data.</param>
        /// <param name="callback">The method to be called when the asynchronous write operation is completed.</param>
        public void BeginWritePeriodTerminated(Stream stream,bool closeStream,object tag,SocketCallBack callback)
        {
            // Allow socket to optimise sends
            m_pSocket.NoDelay = false;

            _BeginWritePeriodTerminated_State state = new _BeginWritePeriodTerminated_State(stream,closeStream,tag,callback);
            BeginProcessingWritePeriodTerminated(state);
        }
Пример #2
0
        /// <summary>
        /// Reads data block from state.Stream and begins writing it to socket.
        /// This method is looped while all data has been readed from state.Stream, then sate.Callback is called.
        /// </summary>
        /// <param name="state">State info.</param>        
        private void BeginProcessingWritePeriodTerminated(_BeginWritePeriodTerminated_State state)
        {
            /* Before sending a line of text, check the first character of the line.
               If it is a period, one additional period is inserted at the beginning of the line.
            */

            byte[] buffer           = new byte[4000];
            int    positionInBuffer = 0;
            int    currentByte      = state.Stream.ReadByte();
            while(currentByte > -1){
                // We have CRLF, mark it up
                if(state.LastByte == '\r' && currentByte == '\n'){
                    state.HasCRLF = true;
                }
                // There is CRLF + current byte
                else if(state.HasCRLF){
                    // If it is a period, one additional period is inserted at the beginning of the line.
                    if(currentByte == '.'){
                        buffer[positionInBuffer] = (byte)'.';
                        positionInBuffer++;
                    }

                    // CRLF handled, reset it
                    state.HasCRLF = false;
                }

                buffer[positionInBuffer] = (byte)currentByte;
                positionInBuffer++;

                state.LastByte = currentByte;

                // Buffer is filled up, begin writing buffer to socket.
                if(positionInBuffer > (4000 - 10)){
                    state.CountSent += positionInBuffer;
                    m_WrittenCount += positionInBuffer;

                    if(m_SSL){
                        m_pSslStream.BeginWrite(buffer,0,positionInBuffer,this.OnBeginWritePeriodTerminatedCallback,state);
                    }
                    else{
                        m_pSocketStream.BeginWrite(buffer,0,positionInBuffer,this.OnBeginWritePeriodTerminatedCallback,state);
                    }
                    return;
                }

                currentByte = state.Stream.ReadByte();
            }

            // We have readed all data, write .<CRLF> or <CRLF>.<CRLF> if data not <CRLF> terminated.
            if(!state.HasCRLF){
                buffer[positionInBuffer] = (byte)'\r';
                positionInBuffer++;
                buffer[positionInBuffer] = (byte)'\n';
                positionInBuffer++;
            }

            buffer[positionInBuffer] = (byte)'.';
            positionInBuffer++;
            buffer[positionInBuffer] = (byte)'\r';
            positionInBuffer++;
            buffer[positionInBuffer] = (byte)'\n';
            positionInBuffer++;

            if(m_SSL){
                m_pSslStream.Write(buffer,0,positionInBuffer);
            }
            else{
                m_pSocketStream.Write(buffer,0,positionInBuffer);
            }
            state.CountSent += positionInBuffer;
            m_WrittenCount += positionInBuffer;
            m_LastActivityDate = DateTime.Now;
            //-------------------------------------------------------------------------------------//

            // Logging stuff
            if(m_pLogger != null){
                if(state.CountSent < 200){
                    m_pLogger.AddSendEntry(m_pEncoding.GetString(buffer),buffer.Length);
                }
                else{
                    m_pLogger.AddSendEntry("Binary data, sent " + state.CountSent.ToString() + " bytes.",state.CountSent);
                }
            }

            // We don't need stream any more, close it
            if(state.CloseStream){
                try{
                    state.Stream.Close();
                }
                catch{
                }
            }

            // Data sent ok, call callback.
            if(state.Callback != null){
                state.Callback(SocketCallBackResult.Ok,state.CountSent,null,state.Tag);
            }
        }