private void ProccessData_Len(_SocketState state) { long dataAvailable = this.AvailableInBuffer; if (dataAvailable > 0) { byte[] data = new byte[dataAvailable]; // Ensure that we don't get more data than needed !!! if (dataAvailable > (state.LenthToRead - state.ReadCount)) { data = new byte[state.LenthToRead - state.ReadCount]; } int countRecieved = this.ReceiveFromFuffer(data); // Increase readed count state.ReadCount += data.Length; // Message size exceeded, just don't store it if (state.ReadCount < state.MaxLength) { state.Stream.Write(data, 0, data.Length); } } // We got all data successfully, call EndRecieve call back if (state.ReadCount == state.LenthToRead) { // Message size exceeded if (state.ReadCount > state.MaxLength) { if (state.Callback != null) { state.Callback(SocketCallBackResult.LengthExceeded, state.ReadCount, null, state.Tag); } } else { // Logging stuff if (m_pLogger != null) { m_pLogger.AddReadEntry("Big binary, readed " + state.ReadCount.ToString() + " bytes.", state.ReadCount); } if (state.Callback != null) { state.Callback(SocketCallBackResult.Ok, state.ReadCount, null, state.Tag); } } } else { // Recieve next bytes byte[] buff = new byte[1024]; state.RecvBuffer = buff; this.BeginReceive(buff, 0, buff.Length, 0, new AsyncCallback(OnRecievedData), state); } }
/// <summary> /// Is called from asynchronous socket if data is recieved. /// </summary> /// <param name="a"></param> private void OnRecievedData(IAsyncResult a) { _SocketState state = (_SocketState)a.AsyncState; try { // 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 (!this.IsClosed) { int countReaded = this.EndReceive(a); if (countReaded > 0) { this.AppendBuffer(state.RecvBuffer, countReaded); if (state.ReadType == ReadType.Terminator) { ProccessData_Term(state); } else { ProccessData_Len(state); } } // Client disconnected else if (state.Callback != null) { state.Callback(SocketCallBackResult.SocketClosed, state.ReadCount, null, state.Tag); } } OnActivity(); } catch (Exception x) { if (state.Callback != null) { state.Callback(SocketCallBackResult.Exception, state.ReadCount, x, state.Tag); } } }
private void ProccessData_Term(_SocketState state) { while (state.NextRead > 0) { // We used buffer, request more data if (this.AvailableInBuffer < state.NextRead) { // Store nextReadWriteLen for next call of this command // state.NextRead = state.NextRead; // Recieve next bytes byte[] buff = new byte[4000]; state.RecvBuffer = buff; this.BeginReceive(buff, 0, buff.Length, 0, new AsyncCallback(OnRecievedData), state); // End this method, if data arrives, this method is called again return; } //Read byte(s) byte[] b = new byte[state.NextRead]; int countRecieved = this.ReceiveFromFuffer(b); // Increase readed count state.ReadCount += countRecieved; // Write byte(s) to buffer, if length isn't exceeded. if (state.ReadCount < state.MaxLength) { state.Stream.Write(b, 0, countRecieved); } // Write to stack(terminator checker) state.NextRead = state.Stack.Push(b, countRecieved); } // If we reach so far, then we have successfully readed data if (state.ReadCount < state.MaxLength) { // Remove "removeFromEnd" from end if (state.RemFromEnd.Length > 0 && state.Stream.Length > state.RemFromEnd.Length) { state.Stream.SetLength(state.Stream.Length - state.RemFromEnd.Length); } state.Stream.Position = 0; // Logging stuff if (m_pLogger != null) { if (state.Stream.Length < 200 && state.Stream is MemoryStream) { MemoryStream ms = (MemoryStream)state.Stream; m_pLogger.AddReadEntry(m_pEncoding.GetString(ms.ToArray()), state.ReadCount); } else { m_pLogger.AddReadEntry("Big binary, readed " + state.ReadCount.ToString() + " bytes.", state.ReadCount); } } // We got all data successfully, call EndRecieve call back if (state.Callback != null) { state.Callback(SocketCallBackResult.Ok, state.ReadCount, null, state.Tag); } } else if (state.Callback != null) { state.Callback(SocketCallBackResult.LengthExceeded, state.ReadCount, null, state.Tag); } }
/// <summary> /// Begins asynchronous data reading. /// </summary> /// <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> public void BeginReadData(Stream strm, long lengthToRead, long maxLength, object tag, SocketCallBack callBack) { _SocketState state = new _SocketState(strm, lengthToRead, maxLength, tag, callBack); ProccessData_Len(state); }
/// <summary> /// Begins asynchronous data reading. /// </summary> /// <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> public void BeginReadData(Stream strm, long maxLength, string terminator, string removeFromEnd, object tag, SocketCallBack callBack) { _SocketState state = new _SocketState(strm, maxLength, terminator, removeFromEnd, tag, callBack); ProccessData_Term(state); }