/// <summary> /// send data callback /// </summary> /// <param name="result"></param> private void sendDataCallback(IAsyncResult result) { SocketSendState sendState = (SocketSendState)result.AsyncState; try { int sendByte = _workingSocket.EndSend(result); sendState.Offset += sendByte; if (!_isSendingHeader) { _sendingProgress.Completed += sendByte; } } catch (Exception ex) { onClose(ex); return; } if (sendState.Offset - sendState.StartIndex < sendState.Length) { //send the remain data beginSendData(sendState); } else { //when send header and conent at one time, this object will not equal NULL if (_toBeSendData != null) { //here means the header has been send complete, //now should prepare to send body _isSendingHeader = false; sendState = _toBeSendData; _toBeSendData = null; beginSendData(sendState); } else { //raise the SendComplete event SendCompleteEventArgs arg = new SendCompleteEventArgs( _lastSendHeader, sendState.Length, _sendingProgress.Completed, _sendingProgress.Total); try { SendComplete(this, arg); } catch (Exception ex) { onClose(ex); return; } } }//end if }
/// <summary> /// Combine with 'Send(IProtocolHeader, long)' method to send big data /// </summary> /// <param name="data"></param> /// <param name="offset"></param> /// <param name="length"></param> public void ContinueSendingBody(byte[] data, int offset, int length) { //NOTE:: //the 'SendComplete' event will raise when the body has been send each time. if (_isClosing) { throw new AsyncSocketException("Connection has closed"); } _isSendingHeader = false; _toBeSendData = null; SocketSendState sendState = new SocketSendState(data, offset, length); beginSendData(sendState); }
/// <summary> /// Send header only (without body) /// </summary> /// <param name="header"></param> public void Send(IProtocolHeader header) { if (_isClosing) { throw new AsyncSocketException("Connection has closed"); } _lastSendHeader = header; _isSendingHeader = true; _toBeSendData = null; _sendingProgress.Reset(); byte[] headerData = header.GetHeaderRawData(); SocketSendState sendState = new SocketSendState(headerData, 0, headerData.Length); beginSendData(sendState); }
/// <summary> /// Send header and body at one time /// </summary> /// <param name="header"></param> /// <param name="data"></param> /// <param name="offset"></param> /// <param name="length"></param> public void Send(IProtocolHeader header, byte[] data, int offset, int length) { //NOTE:: //when this operation complete, it raise SendComplete event only once when //the header and body all send complete. if (_isClosing) { throw new AsyncSocketException("Connection has closed"); } _lastSendHeader = header; _isSendingHeader = true; _toBeSendData = new SocketSendState(data, offset, length); _sendingProgress.Reset(); _sendingProgress.Total = length; byte[] headerData = header.GetHeaderRawData(); SocketSendState sendState = new SocketSendState(headerData, 0, headerData.Length); beginSendData(sendState); }
/// <summary> /// Combine with 'ContinueSendingBody' method to send big data /// </summary> /// <param name="header"></param> /// <param name="totalPlanSendingLength"></param> public void Send(IProtocolHeader header, long totalPlanSendingLength) { //NOTE:: //when need sending big data, call this method first, //and when this header send complete, call "ContinueSendingBody" many times //to send the body until all has been send. if (_isClosing) { throw new AsyncSocketException("Connection has closed"); } _lastSendHeader = header; _isSendingHeader = true; _toBeSendData = null; _sendingProgress.Reset(); _sendingProgress.Total = totalPlanSendingLength; byte[] headerData = header.GetHeaderRawData(); SocketSendState sendState = new SocketSendState(headerData, 0, headerData.Length); beginSendData(sendState); }
/// <summary> /// begin send data /// </summary> /// <param name="sendState"></param> private void beginSendData(SocketSendState sendState) { try { //calculate the length need to be send at this time int sendByte = sendState.Length - (sendState.Offset - sendState.StartIndex); if (sendByte > TRANSFER_BLOCK_LENGTH) { sendByte = TRANSFER_BLOCK_LENGTH; } _workingSocket.BeginSend( sendState.Data, sendState.Offset, sendByte, SocketFlags.None, new AsyncCallback(sendDataCallback), sendState); } catch (Exception ex) { onClose(ex); } }