Sokcet + buffer. Socket data reads are buffered. At first Recieve returns data from internal buffer and if no data available, gets more from socket. Socket buffer is also user settable, you can add data to socket buffer directly with AppendBuffer().
예제 #1
0
        /// <summary>
        /// Is called from asynchronous socket if data is sended.
        /// </summary>
        /// <param name="a"></param>
        private static void OnSendedData(IAsyncResult a)
        {
            object[]       param    = (object[])a.AsyncState;
            BufferedSocket socket   = (BufferedSocket)param[0];
            MemoryStream   strm     = (MemoryStream)param[1];
            object         tag      = param[2];
            SocketCallBack callBack = (SocketCallBack)param[3];

            try{
                int countSended = socket.Socket.EndSend(a);

                // Send next data block
                if (strm.Position < strm.Length)
                {
                    SendDataBlock(socket, strm, tag, callBack);
                }
                // We sended all data
                else
                {
                    callBack(SocketCallBackResult.Ok, strm.Position, null, tag);
                }
            }
            catch (Exception x) {
                callBack(SocketCallBackResult.Exception, strm.Position, x, tag);
            }
        }
예제 #2
0
        /// <summary>
        /// Starts sending block of data.
        /// </summary>
        /// <param name="socket">Socket where to send data.</param>
        /// <param name="strm">Data to send.</param>
        /// <param name="tag">User data.</param>
        /// <param name="callBack">Method to call, if send completes.</param>
        private static void SendDataBlock(BufferedSocket socket, Stream strm, object tag, SocketCallBack callBack)
        {
            byte[] data        = new byte[1024];
            int    countReaded = strm.Read(data, 0, data.Length);

            socket.Socket.BeginSend(data, 0, countReaded, 0, new AsyncCallback(OnSendedData), new object[] { socket, strm, tag, callBack });
        }
예제 #3
0
        /// <summary>
        /// Sends line to Socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="lineData"></param>
        public static void SendLine(BufferedSocket socket, string lineData)
        {
            byte[] byte_data   = System.Text.Encoding.Default.GetBytes(lineData + "\r\n");
            int    countSended = socket.Send(byte_data);

            if (countSended != byte_data.Length)
            {
                throw new Exception("Send error, didn't send all bytes !");
            }
        }
예제 #4
0
        /// <summary>
        /// Reads line of data from Socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="maxLen"></param>
        /// <param name="idleTimeOut"></param>
        /// <returns></returns>
        public static string ReadLine(BufferedSocket socket, int maxLen, int idleTimeOut)
        {
            MemoryStream  storeStream = null;
            ReadReplyCode code        = ReadData(socket, out storeStream, maxLen, idleTimeOut, "\r\n", "\r\n");

            if (code != ReadReplyCode.Ok)
            {
                throw new ReadException(code, code.ToString());
            }

            return(System.Text.Encoding.Default.GetString(storeStream.ToArray()).Trim());
        }
예제 #5
0
        private string m_UserName = ""; // Holds loggedIn UserName.

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="clientSocket">Referance to socket.</param>
        /// <param name="server">Referance to FTP server.</param>
        /// <param name="sessionID">Session ID which is assigned to this session.</param>
        /// <param name="logWriter">Log writer.</param>
        public FTP_Session(Socket clientSocket,FTP_Server server,string sessionID,_LogWriter logWriter)
        {
            m_pSocket    = new BufferedSocket(clientSocket);
            m_pServer          = server;
            m_SessionID        = sessionID;
            m_pLogWriter       = logWriter;
            m_SessionStartTime = DateTime.Now;
            m_LastDataTime     = DateTime.Now;

            m_pSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1);

            // Start session proccessing
            StartSession();
        }
예제 #6
0
        /// <summary>
        /// Reads specified count of data from Socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="count">Number of bytes to read.</param>
        /// <param name="storeStrm"></param>
        /// <param name="storeToStream">If true stores readed data to stream, otherwise just junks specified amount of data.</param>
        /// <param name="cmdIdleTimeOut"></param>
        /// <returns></returns>
        public static ReadReplyCode ReadData(BufferedSocket socket, long count, Stream storeStrm, bool storeToStream, int cmdIdleTimeOut)
        {
            ReadReplyCode replyCode = ReadReplyCode.Ok;

            try{
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, cmdIdleTimeOut);

                long readedCount = 0;
                while (readedCount < count)
                {
                    byte[] b = new byte[4000];
                    // Ensure that we don't get more data than needed
                    if ((count - readedCount) < 4000)
                    {
                        b = new byte[count - readedCount];
                    }

                    int countRecieved = socket.Receive(b);
                    if (countRecieved > 0)
                    {
                        readedCount += countRecieved;

                        if (storeToStream)
                        {
                            storeStrm.Write(b, 0, countRecieved);
                        }
                    }
                    // Client disconnected
                    else
                    {
                        throw new Exception("Client disconnected");
                    }
                }
            }
            catch (Exception x) {
                replyCode = ReadReplyCode.UnKnownError;

                if (x is SocketException)
                {
                    SocketException xS = (SocketException)x;
                    if (xS.ErrorCode == 10060)
                    {
                        replyCode = ReadReplyCode.TimeOut;
                    }
                }
            }

            return(replyCode);
        }
예제 #7
0
        private string m_UserName = ""; // Holds loggedIn UserName.

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="clientSocket">Referance to socket.</param>
        /// <param name="server">Referance to IMAP server.</param>
        /// <param name="logWriter">Log writer.</param>
        internal IMAP_Session(Socket clientSocket,IMAP_Server server,_LogWriter logWriter)
        {
            m_pSocket    = new BufferedSocket(clientSocket);
            m_pServer    = server;
            m_pLogWriter = logWriter;

            m_SessionID        = Guid.NewGuid().ToString();
            m_SessionStartTime = DateTime.Now;
            m_LastDataTime     = DateTime.Now;

            m_pSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1);

            // Start session proccessing
            StartSession();
        }
예제 #8
0
        /// <summary>
        /// Begins asynchronous recieveing.
        /// </summary>
        /// <param name="socket">Socket from where to get data.</param>
        /// <param name="strm">Stream where to store data.</param>
        /// <param name="lengthToRead">Length of data to read.</param>
        /// <param name="maxLength">Maximum length of data which may read.</param>
        /// <param name="tag">User data.</param>
        /// <param name="callBack">Method to call, if receive completes.</param>
        /// <param name="activityCallback">Method to call, if data block is completed. Data is retrieved as blocks,
        /// for example data1 data2 ..., activity callback is called foreach data block.</param>
        public static void BeginRecieve(BufferedSocket socket, MemoryStream strm, long lengthToRead, long maxLength, object tag, SocketCallBack callBack, SocketActivityCallback activityCallback)
        {
            Hashtable param = new Hashtable();

            param.Add("recieveType", "len");
            param.Add("socket", socket);
            param.Add("strm", strm);
            param.Add("lengthToRead", lengthToRead);
            param.Add("maxLength", maxLength);
            param.Add("tag", tag);
            param.Add("callBack", callBack);
            param.Add("activityCallback", activityCallback);
            param.Add("readedCount", (long)0);
            param.Add("recieveBuffer", new byte[0]);

            ProccessData_Len(param);
        }
예제 #9
0
        /// <summary>
        /// Is called from asynchronous socket if data is recieved.
        /// </summary>
        /// <param name="a"></param>
        private static void OnRecievedData(IAsyncResult a)
        {
            Hashtable              param            = (Hashtable)a.AsyncState;
            BufferedSocket         socket           = (BufferedSocket)param["socket"];
            object                 tag              = param["tag"];
            SocketCallBack         callBack         = (SocketCallBack)param["callBack"];
            SocketActivityCallback activityCallback = (SocketActivityCallback)param["activityCallback"];

            byte[] buffer = (byte[])param["recieveBuffer"];

            try{
                // Call activity call back, if specified
                if (activityCallback != null)
                {
                    activityCallback(tag);
                }

                // Socket is closed by session, we don't need to get data or call callback method.
                // This mainlty happens when session timesout and session is ended.
                if (!socket.IsClosed)
                {
                    int countReaded = socket.EndReceive(a);
                    if (countReaded > 0)
                    {
                        socket.AppendBuffer(buffer, countReaded);

                        if (param["recieveType"].ToString() == "term")
                        {
                            ProccessData_Term(param);
                        }
                        else
                        {
                            ProccessData_Len(param);
                        }
                    }
                    // Client disconnected
                    else
                    {
                        callBack(SocketCallBackResult.SocketClosed, (long)param["readedCount"], null, tag);
                    }
                }
            }
            catch (Exception x) {
                callBack(SocketCallBackResult.Exception, (long)param["readedCount"], x, tag);
            }
        }
예제 #10
0
        private static void ProccessData_Len(Hashtable param)
        {
            BufferedSocket socket   = (BufferedSocket)param["socket"];
            MemoryStream   strm     = (MemoryStream)param["strm"];
            object         tag      = param["tag"];
            SocketCallBack callBack = (SocketCallBack)param["callBack"];

            long dataAvailable = socket.AvailableInBuffer;

            if (dataAvailable > 0)
            {
                byte[] data = new byte[dataAvailable];
                // Ensure that we don't get more data than needed !!!
                if (dataAvailable > ((long)param["lengthToRead"] - (long)param["readedCount"]))
                {
                    data = new byte[(long)param["lengthToRead"] - (long)param["readedCount"]];
                }
                int countRecieved = socket.ReceiveFromFuffer(data);

                // Increase readed count
                param["readedCount"] = ((long)param["readedCount"] + data.Length);

                if ((long)param["readedCount"] < (long)param["maxLength"])
                {
                    strm.Write(data, 0, data.Length);
                }
                // Message size exceeded, we must junk stream data.
                else if (strm.Length > 0)
                {
                    strm.SetLength(0);
                }
            }

            // We got all data successfully, call EndRecieve call back
            if ((long)param["readedCount"] == (long)param["lengthToRead"])
            {
                callBack(SocketCallBackResult.Ok, (long)param["readedCount"], null, tag);
            }
            else
            {
                // Recieve next bytes
                byte[] buff = new byte[1024];
                param["recieveBuffer"] = buff;
                socket.BeginReceive(buff, 0, buff.Length, 0, new AsyncCallback(OnRecievedData), param);
            }
        }
예제 #11
0
        /// <summary>
        /// Begins asynchronous recieveing.
        /// </summary>
        /// <param name="socket">Socket from where to get data.</param>
        /// <param name="strm">Stream where to store data.</param>
        /// <param name="maxLength">Maximum length of data which may read.</param>
        /// <param name="terminator">Terminator string which terminates reading. eg '\r\n'.</param>
        /// <param name="removeFromEnd">Removes following string at end of data.</param>
        /// <param name="tag">User data.</param>
        /// <param name="callBack">Method to call, if receive completes.</param>
        /// <param name="activityCallback">Method to call, if data block is completed. Data is retrieved as blocks, 
        /// for example data1 data2 ..., activity callback is called foreach data block.</param>
        public static void BeginRecieve(BufferedSocket socket,MemoryStream strm,long maxLength,string terminator,string removeFromEnd,object tag,SocketCallBack callBack,SocketActivityCallback activityCallback)
        {
            Hashtable param = new Hashtable();
            param.Add("recieveType","term");
            param.Add("socket",socket);
            param.Add("strm",strm);
            param.Add("removeFromEnd",removeFromEnd);
            param.Add("tag",tag);
            param.Add("callBack",callBack);
            param.Add("activityCallback",activityCallback);
            param.Add("stack",new _FixedStack(terminator));
            param.Add("nextReadWriteLen",1);
            param.Add("readedCount",(long)0);
            param.Add("maxLength",maxLength);
            param.Add("recieveBuffer",new byte[0]);

            ProccessData_Term(param);
        }
예제 #12
0
        private string m_UserName = ""; // Holds loggedIn UserName.

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="clientSocket">Referance to socket.</param>
        /// <param name="server">Referance to SMTP server.</param>
        /// <param name="logWriter">Log writer.</param>
        internal SMTP_Session(Socket clientSocket,SMTP_Server server,_LogWriter logWriter)
        {
            m_pSocket    = new BufferedSocket(clientSocket);
            m_pServer    = server;
            m_pLogWriter = logWriter;

            m_pMsgStream   = new MemoryStream();
            m_SessionID    = Guid.NewGuid().ToString();
            m_BodyType     = BodyType.x7_bit;
            m_Forward_path = new Hashtable();
            m_CmdValidator = new SMTP_Cmd_Validator();
            m_SessionStart = DateTime.Now;
            m_LastDataTime = DateTime.Now;

            m_pSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1);

            // Start session proccessing
            StartSession();
        }
예제 #13
0
        /// <summary>
        /// Begins asynchronous recieveing.
        /// </summary>
        /// <param name="socket">Socket from where to get data.</param>
        /// <param name="strm">Stream where to store data.</param>
        /// <param name="maxLength">Maximum length of data which may read.</param>
        /// <param name="terminator">Terminator string which terminates reading. eg '\r\n'.</param>
        /// <param name="removeFromEnd">Removes following string at end of data.</param>
        /// <param name="tag">User data.</param>
        /// <param name="callBack">Method to call, if receive completes.</param>
        /// <param name="activityCallback">Method to call, if data block is completed. Data is retrieved as blocks,
        /// for example data1 data2 ..., activity callback is called foreach data block.</param>
        public static void BeginRecieve(BufferedSocket socket, MemoryStream strm, long maxLength, string terminator, string removeFromEnd, object tag, SocketCallBack callBack, SocketActivityCallback activityCallback)
        {
            Hashtable param = new Hashtable();

            param.Add("recieveType", "term");
            param.Add("socket", socket);
            param.Add("strm", strm);
            param.Add("removeFromEnd", removeFromEnd);
            param.Add("tag", tag);
            param.Add("callBack", callBack);
            param.Add("activityCallback", activityCallback);
            param.Add("stack", new _FixedStack(terminator));
            param.Add("nextReadWriteLen", 1);
            param.Add("readedCount", (long)0);
            param.Add("maxLength", maxLength);
            param.Add("recieveBuffer", new byte[0]);

            ProccessData_Term(param);
        }
예제 #14
0
        private string m_UserName = ""; // Holds loggedIn UserName.

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="clientSocket">Referance to socket.</param>
        /// <param name="server">Referance to IMAP server.</param>
        /// <param name="logWriter">Log writer.</param>
        internal IMAP_Session(Socket clientSocket,IMAP_Server server,SocketLogger logWriter)
        {
            m_pSocket = new BufferedSocket(clientSocket);
            m_pServer = server;

            m_SessionID        = Guid.NewGuid().ToString();
            m_SessionStartTime = DateTime.Now;
            m_LastDataTime     = DateTime.Now;

            if(m_pServer.LogCommands){
                m_pSocket.Logger = logWriter;
                m_pSocket.Logger.SessionID = m_SessionID;
            }

            m_pSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.NoDelay,1);
            m_pSocket.Activity += new EventHandler(OnSocketActivity);

            // Start session proccessing
            StartSession();
        }
예제 #15
0
        /// <summary>
        /// Reads reply from socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="replyData">Data that has been readen from socket.</param>
        /// <param name="maxLength">Maximum Length of data which may read.</param>
        /// <param name="cmdIdleTimeOut">Command idle time out in milliseconds.</param>
        /// <param name="terminator">Terminator string which terminates reading. eg '\r\n'.</param>
        /// <param name="removeFromEnd">Removes following string from reply.NOTE: removes only if ReadReplyCode is Ok.</param>		
        /// <returns>Return reply code.</returns>
        public static ReadReplyCode ReadData(BufferedSocket socket,out MemoryStream replyData,int maxLength,int cmdIdleTimeOut,string terminator,string removeFromEnd)
        {
            ReadReplyCode replyCode = ReadReplyCode.Ok;
            replyData = null;

            try{
                socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,cmdIdleTimeOut);

                replyData = new MemoryStream();
                _FixedStack stack = new _FixedStack(terminator);
                int nextReadWriteLen = 1;

                while(nextReadWriteLen > 0){
                    //Read byte(s)
                    byte[] b = new byte[nextReadWriteLen];
                    int countRecieved = socket.Receive(b);
                    if(countRecieved > 0){
                        // Write byte(s) to buffer, if length isn't exceeded.
                        if(replyCode != ReadReplyCode.LengthExceeded){
                            replyData.Write(b,0,countRecieved);
                        }

                        // Write to stack(terminator checker)
                        nextReadWriteLen = stack.Push(b,countRecieved);

                        //---- Check if maximum length is exceeded ---------------------------------//
                        if(replyCode != ReadReplyCode.LengthExceeded && replyData.Length > maxLength){
                            replyCode = ReadReplyCode.LengthExceeded;
                        }
                        //--------------------------------------------------------------------------//
                    }
                    // Client disconnected
                    else{
                        throw new Exception("Client disconnected");
                    }
                }

                // If reply is ok then remove chars if any specified by 'removeFromEnd'.
                if(replyCode == ReadReplyCode.Ok && removeFromEnd.Length > 0){
                    replyData.SetLength(replyData.Length - removeFromEnd.Length);
                }
            }
            catch(Exception x){
                replyCode = ReadReplyCode.UnKnownError;

                if(x is SocketException){
                    SocketException xS = (SocketException)x;
                    if(xS.ErrorCode == 10060){
                        replyCode = ReadReplyCode.TimeOut;
                    }
                }
            }

            return replyCode;
        }
예제 #16
0
        /// <summary>
        /// Ends session, closes socket.
        /// </summary>
        private void EndSession()
        {
            try{
                // Write logs to log file, if needed
                if(m_pServer.LogCommands){
                    m_pSocket.Logger.Flush();
                }

                if(m_pSocket != null){
                    m_pSocket.Shutdown(SocketShutdown.Both);
                    m_pSocket.Close();
                    m_pSocket = null;
                }
            }
            catch{ // We don't need to check errors here, because they only may be Socket closing errors.
            }
            finally{
                m_pServer.RemoveSession(this);
            }
        }
예제 #17
0
 /// <summary>
 /// Reads line of data from Socket.
 /// </summary>
 /// <param name="socket"></param>
 /// <returns></returns>
 public static string ReadLine(BufferedSocket socket)
 {
     return(ReadLine(socket, 500, 60000));
 }
예제 #18
0
 /// <summary>
 /// Begins asynchronous sending.
 /// </summary>
 /// <param name="socket">Socket where to send data.</param>
 /// <param name="strm">Data to send.</param>
 /// <param name="tag">User data.</param>
 /// <param name="callBack">Method to call, if send completes.</param>
 public static void BeginSend(BufferedSocket socket, Stream strm, object tag, SocketCallBack callBack)
 {
     SendDataBlock(socket, strm, tag, callBack);
 }
예제 #19
0
/*
 *              /// <summary>
 *              /// Reads specified count of data from Socket.
 *              /// </summary>
 *              /// <param name="socket"></param>
 *              /// <param name="count">Number of bytes to read.</param>
 *              /// <param name="storeStrm"></param>
 *              /// <param name="storeToStream">If true stores readed data to stream, otherwise just junks data.</param>
 *              /// <param name="cmdIdleTimeOut"></param>
 *              /// <returns></returns>
 *              public static ReadReplyCode ReadData(Socket socket,long count,Stream storeStrm,bool storeToStream,int cmdIdleTimeOut)
 *              {
 *                      ReadReplyCode replyCode = ReadReplyCode.Ok;
 *
 *                      try{
 *                              socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,cmdIdleTimeOut);
 *
 *                              long readedCount  = 0;
 *                              while(readedCount < count){
 *                                      byte[] b = new byte[4000];
 *                                      // Ensure that we don't get more data than needed !!!
 *                                      if((count - readedCount) < 4000){
 *                                              b = new byte[count - readedCount];
 *                                      }
 *
 *                                      int countRecieved = socket.Receive(b);
 *                                      if(countRecieved > 0){
 *                                              readedCount += countRecieved;
 *
 *                                              if(storeToStream){
 *                                                      storeStrm.Write(b,0,countRecieved);
 *                                              }
 *                                      }
 *                                      // Client disconnected
 *                                      else{
 *                                              throw new Exception("Client disconnected");
 *                                      }
 *                              }
 *                      }
 *                      catch(Exception x){Console.WriteLine(x.Message);
 *                              replyCode = ReadReplyCode.UnKnownError;
 *                      }
 *
 *                      return replyCode;
 *              }
 */
        #endregion

        #region method ReadData

        /// <summary>
        /// Reads reply from socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="replyData">Data that has been readen from socket.</param>
        /// <param name="maxLength">Maximum Length of data which may read.</param>
        /// <param name="cmdIdleTimeOut">Command idle time out in milliseconds.</param>
        /// <param name="terminator">Terminator string which terminates reading. eg '\r\n'.</param>
        /// <param name="removeFromEnd">Removes following string from reply.NOTE: removes only if ReadReplyCode is Ok.</param>
        /// <returns>Return reply code.</returns>
        public static ReadReplyCode ReadData(BufferedSocket socket, out MemoryStream replyData, int maxLength, int cmdIdleTimeOut, string terminator, string removeFromEnd)
        {
            ReadReplyCode replyCode = ReadReplyCode.Ok;

            replyData = null;

            try{
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, cmdIdleTimeOut);

                replyData = new MemoryStream();
                _FixedStack stack            = new _FixedStack(terminator);
                int         nextReadWriteLen = 1;

                while (nextReadWriteLen > 0)
                {
                    //Read byte(s)
                    byte[] b             = new byte[nextReadWriteLen];
                    int    countRecieved = socket.Receive(b);
                    if (countRecieved > 0)
                    {
                        // Write byte(s) to buffer, if length isn't exceeded.
                        if (replyCode != ReadReplyCode.LengthExceeded)
                        {
                            replyData.Write(b, 0, countRecieved);
                        }

                        // Write to stack(terminator checker)
                        nextReadWriteLen = stack.Push(b, countRecieved);

                        //---- Check if maximum length is exceeded ---------------------------------//
                        if (replyCode != ReadReplyCode.LengthExceeded && replyData.Length > maxLength)
                        {
                            replyCode = ReadReplyCode.LengthExceeded;
                        }
                        //--------------------------------------------------------------------------//
                    }
                    // Client disconnected
                    else
                    {
                        throw new Exception("Client disconnected");
                    }
                }

                // If reply is ok then remove chars if any specified by 'removeFromEnd'.
                if (replyCode == ReadReplyCode.Ok && removeFromEnd.Length > 0)
                {
                    replyData.SetLength(replyData.Length - removeFromEnd.Length);
                }
            }
            catch (Exception x) {
                replyCode = ReadReplyCode.UnKnownError;

                if (x is SocketException)
                {
                    SocketException xS = (SocketException)x;
                    if (xS.ErrorCode == 10060)
                    {
                        replyCode = ReadReplyCode.TimeOut;
                    }
                }
            }

            return(replyCode);
        }
예제 #20
0
        private static void ProccessData_Term(Hashtable param)
        {
            BufferedSocket socket           = (BufferedSocket)param["socket"];
            MemoryStream   strm             = (MemoryStream)param["strm"];
            string         removeFromEnd    = (string)param["removeFromEnd"];
            _FixedStack    stack            = (_FixedStack)param["stack"];
            int            nextReadWriteLen = (int)param["nextReadWriteLen"];
            object         tag      = param["tag"];
            SocketCallBack callBack = (SocketCallBack)param["callBack"];

            while (nextReadWriteLen > 0)
            {
                // We used buffer, request more data
                if (socket.AvailableInBuffer < nextReadWriteLen)
                {
                    // Store nextReadWriteLen for next call of this command
                    param["nextReadWriteLen"] = nextReadWriteLen;

                    // Recieve next bytes
                    byte[] buff = new byte[1024];
                    param["recieveBuffer"] = buff;
                    socket.BeginReceive(buff, 0, buff.Length, 0, new AsyncCallback(OnRecievedData), param);

                    // End this method, if data arrives, this method is called again
                    return;
                }

                //Read byte(s)
                byte[] b             = new byte[nextReadWriteLen];
                int    countRecieved = socket.ReceiveFromFuffer(b);

                // Increase readed count
                param["readedCount"] = ((long)param["readedCount"] + countRecieved);

                // Write byte(s) to buffer, if length isn't exceeded.
                if ((long)param["readedCount"] < (long)param["maxLength"])
                {
                    strm.Write(b, 0, countRecieved);
                }
                // Message size exceeded, we must junk stream data.
                else if (strm.Length > 0)
                {
                    strm.SetLength(0);
                }

                // Write to stack(terminator checker)
                nextReadWriteLen = stack.Push(b, countRecieved);
            }


            // If we reach so far, then we have successfully readed data

            if ((long)param["readedCount"] < (long)param["maxLength"])
            {
                // Remove "removeFromEnd" from end
                if (removeFromEnd.Length > 0 && strm.Length > removeFromEnd.Length)
                {
                    strm.SetLength(strm.Length - removeFromEnd.Length);
                }
                strm.Position = 0;

                // We got all data successfully, call EndRecieve call back
                callBack(SocketCallBackResult.Ok, (long)param["readedCount"], null, tag);
            }
            else
            {
                callBack(SocketCallBackResult.LengthExceeded, (long)param["readedCount"], null, tag);
            }
        }
예제 #21
0
        /// <summary>
        /// Reads specified count of data from Socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="count">Number of bytes to read.</param>
        /// <param name="storeStrm"></param>
        /// <param name="storeToStream">If true stores readed data to stream, otherwise just junks specified amount of data.</param>
        /// <param name="cmdIdleTimeOut"></param>
        /// <returns></returns>
        public static ReadReplyCode ReadData(BufferedSocket socket,long count,Stream storeStrm,bool storeToStream,int cmdIdleTimeOut)
        {
            ReadReplyCode replyCode = ReadReplyCode.Ok;

            try{
                socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,cmdIdleTimeOut);

                long readedCount  = 0;
                while(readedCount < count){
                    byte[] b = new byte[4000];
                    // Ensure that we don't get more data than needed
                    if((count - readedCount) < 4000){
                        b = new byte[count - readedCount];
                    }

                    int countRecieved = socket.Receive(b);
                    if(countRecieved > 0){
                        readedCount += countRecieved;

                        if(storeToStream){
                            storeStrm.Write(b,0,countRecieved);
                        }
                    }
                    // Client disconnected
                    else{
                        throw new Exception("Client disconnected");
                    }
                }
            }
            catch(Exception x){
                replyCode = ReadReplyCode.UnKnownError;

                if(x is SocketException){
                    SocketException xS = (SocketException)x;
                    if(xS.ErrorCode == 10060){
                        replyCode = ReadReplyCode.TimeOut;
                    }
                }
            }

            return replyCode;
        }
예제 #22
0
 /// <summary>
 /// Begins asynchronous sending.
 /// </summary>
 /// <param name="socket">Socket where to send data.</param>
 /// <param name="strm">Data to send.</param>
 /// <param name="tag">User data.</param>
 /// <param name="callBack">Method to call, if send completes.</param>
 public static void BeginSend(BufferedSocket socket,Stream strm,object tag,SocketCallBack callBack)
 {
     SendDataBlock(socket,strm,tag,callBack);
 }
예제 #23
0
        /// <summary>
        /// Begins asynchronous recieveing.
        /// </summary>
        /// <param name="socket">Socket from where to get data.</param>
        /// <param name="strm">Stream where to store data.</param>
        /// <param name="lengthToRead">Length of data to read.</param>
        /// <param name="maxLength">Maximum length of data which may read.</param>
        /// <param name="tag">User data.</param>
        /// <param name="callBack">Method to call, if receive completes.</param>
        /// <param name="activityCallback">Method to call, if data block is completed. Data is retrieved as blocks, 
        /// for example data1 data2 ..., activity callback is called foreach data block.</param>
        public static void BeginRecieve(BufferedSocket socket,MemoryStream strm,long lengthToRead,long maxLength,object tag,SocketCallBack callBack,SocketActivityCallback activityCallback)
        {
            Hashtable param = new Hashtable();
            param.Add("recieveType","len");
            param.Add("socket",socket);
            param.Add("strm",strm);
            param.Add("lengthToRead",lengthToRead);
            param.Add("maxLength",maxLength);
            param.Add("tag",tag);
            param.Add("callBack",callBack);
            param.Add("activityCallback",activityCallback);
            param.Add("readedCount",(long)0);
            param.Add("recieveBuffer",new byte[0]);

            ProccessData_Len(param);
        }
예제 #24
0
 /// <summary>
 /// Reads line of data from Socket.
 /// </summary>
 /// <param name="socket"></param>
 /// <returns></returns>
 public static string ReadLine(BufferedSocket socket)
 {
     return ReadLine(socket,500,60000);
 }
예제 #25
0
        /// <summary>
        /// Starts sending block of data.
        /// </summary>
        /// <param name="socket">Socket where to send data.</param>
        /// <param name="strm">Data to send.</param>
        /// <param name="tag">User data.</param>
        /// <param name="callBack">Method to call, if send completes.</param>
        private static void SendDataBlock(BufferedSocket socket,Stream strm,object tag,SocketCallBack callBack)
        {
            byte[] data = new byte[1024];
            int countReaded = strm.Read(data,0,data.Length);

            socket.Socket.BeginSend(data,0,countReaded,0,new AsyncCallback(OnSendedData),new object[]{socket,strm,tag,callBack});
        }
예제 #26
0
        /// <summary>
        /// Reads line of data from Socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="maxLen"></param>
        /// <param name="idleTimeOut"></param>
        /// <returns></returns>
        public static string ReadLine(BufferedSocket socket,int maxLen,int idleTimeOut)
        {
            MemoryStream storeStream = null;
            ReadReplyCode code = ReadData(socket,out storeStream,maxLen,idleTimeOut,"\r\n","\r\n");
            if(code != ReadReplyCode.Ok){
                throw new ReadException(code,code.ToString());
            }

            return System.Text.Encoding.Default.GetString(storeStream.ToArray()).Trim();
        }
예제 #27
0
        /// <summary>
        /// Ends session, closes socket.
        /// </summary>
        private void EndSession()
        {
            if(m_pSocket != null){
                m_pSocket.Shutdown(SocketShutdown.Both);
                m_pSocket.Close();
                m_pSocket = null;
            }

            m_pServer.RemoveSession(this);

            // Write logs to log file, if needed
            if(m_pServer.LogCommands){
                m_pLogWriter.AddEntry("//----- Sys: 'Session:'" + this.SessionID + " removed " + DateTime.Now);

                m_pLogWriter.Flush();
            }
        }
예제 #28
0
 /// <summary>
 /// Sends line to Socket.
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="lineData"></param>
 public static void SendLine(BufferedSocket socket,string lineData)
 {
     byte[] byte_data = System.Text.Encoding.Default.GetBytes(lineData + "\r\n");
     int countSended = socket.Send(byte_data);
     if(countSended != byte_data.Length){
         throw new Exception("Send error, didn't send all bytes !");
     }
 }