private void ProcessSend(SocketAsyncEventArgs receiveSendEventArgs) { P2PPortClientConnectionHandler clientHandler = (P2PPortClientConnectionHandler)receiveSendEventArgs.UserToken; if (receiveSendEventArgs.SocketError == SocketError.Success) { clientHandler.sendBytesRemainingCount = clientHandler.sendBytesRemainingCount - receiveSendEventArgs.BytesTransferred; if (clientHandler.sendBytesRemainingCount == 0) { StartReceive(receiveSendEventArgs); } else { clientHandler.bytesSentAlreadyCount += receiveSendEventArgs.BytesTransferred; StartSend(receiveSendEventArgs); } } else { //If we are in this else-statement, there was a socket error. clientHandler.Reset(); CloseClientSocket(receiveSendEventArgs); } }
public bool HandleData(SocketAsyncEventArgs receiveSendEventArgs, P2PPortClientConnectionHandler clientHandler, Int32 remainingBytesToProcess) { bool incomingTcpMessageIsReady = false; if (clientHandler.receivedMessageBytesDoneCount == 0) { clientHandler.CreateNewDataReceivedBuffer(clientHandler.lengthOfCurrentIncomingMessage); } if (remainingBytesToProcess + clientHandler.receivedMessageBytesDoneCount == clientHandler.lengthOfCurrentIncomingMessage) { Buffer.BlockCopy(receiveSendEventArgs.Buffer, clientHandler.receiveMessageOffset, clientHandler.DataReceivedBuffer, clientHandler.receivedMessageBytesDoneCount, remainingBytesToProcess); incomingTcpMessageIsReady = true; } else { try { Buffer.BlockCopy(receiveSendEventArgs.Buffer, clientHandler.receiveMessageOffset, clientHandler.DataReceivedBuffer, clientHandler.receivedMessageBytesDoneCount, remainingBytesToProcess); clientHandler.receiveMessageOffset = clientHandler.receiveMessageOffset - clientHandler.recPrefixBytesDoneThisOp; clientHandler.receivedMessageBytesDoneCount += remainingBytesToProcess; } catch (Exception ex) { string error = ex.Message; } } return(incomingTcpMessageIsReady); }
private void CreateAndStartPort(object portOwner, int listeningPort) { if (!(portOwner is IUseP2PCommunicationsScheme)) { throw (new Exception("The port owner object must implement the interface \'IUseP2PCommunicationsScheme\'")); } this._portOwnerComponent = portOwner; this._ConnectedClientsTable = new Hashtable(); this._startDateTime = DateTime.Now; this._statisticsHandler = new P2PPortStatisticsHandler(); this._listeningPort = listeningPort; string host = System.Net.Dns.GetHostName(); this._IPAddress = CommunicationsLibrary.Utilities.CommunicationsUtilities.GetActiveIPAddress(); this._connectionendpoint = new IPEndPoint(this._IPAddress, this._listeningPort); this._prefixHandler = new PrefixHandler(); this._messageHandler = new DataReceptionHandler(); Int32 totalBytes = P2PNetworkingDefinitions.DATABUFFER_SIZE * NUMBER_OF_SAEA_OBJECTS_FOR_REC_AND_SEND * NUMBER_OF_OPERATIONS_TO_ALLOCATE; Int32 totalBufferBytesInEachSaeaObject = P2PNetworkingDefinitions.DATABUFFER_SIZE * NUMBER_OF_OPERATIONS_TO_ALLOCATE; this._bufferManager = new BufferManager(totalBytes, totalBufferBytesInEachSaeaObject); this._poolOfRecSendEventArgs = new SocketAsyncEventArgsPool(NUMBER_OF_SAEA_OBJECTS_FOR_REC_AND_SEND); this._poolOfAcceptEventArgs = new SocketAsyncEventArgsPool(NUMBER_OF_OPERATIONS_TO_ALLOCATE); this._maxConnectionsEnforcer = new Semaphore(MAX_CONNECTIONS, MAX_CONNECTIONS); //creation of the pool of SEAE Object used to handle incomming connections for (Int32 i = 0; i < MAX_SIMULTANEOUS_ACCEPT_OPS; i++) { SocketAsyncEventArgs SAEA = CreateNewSaeaForAccept(_poolOfAcceptEventArgs); this._poolOfAcceptEventArgs.Push(SAEA); } //creation of the pool of SEAE objects used for send and receive data operations SocketAsyncEventArgs eventArgObjectForPool; for (Int32 i = 0; i < NUMBER_OF_SAEA_OBJECTS_FOR_REC_AND_SEND; i++) { eventArgObjectForPool = new SocketAsyncEventArgs(); this._bufferManager.SetBuffer(eventArgObjectForPool); eventArgObjectForPool.Completed += new EventHandler <SocketAsyncEventArgs>(EventHandling_IO_Completed); P2PPortClientConnectionHandler _P2PClientCnnHandler = new P2PPortClientConnectionHandler(eventArgObjectForPool, eventArgObjectForPool.Offset, eventArgObjectForPool.Offset + P2PNetworkingDefinitions.DATABUFFER_SIZE, P2PNetworkingDefinitions.DATA_SEND_RECEIVE_PREFIX_LENGHT, P2PNetworkingDefinitions.DATA_SEND_RECEIVE_PREFIX_LENGHT); _P2PClientCnnHandler.CreateNewDataReceivedBuffer(P2PNetworkingDefinitions.DATABUFFER_SIZE); eventArgObjectForPool.UserToken = _P2PClientCnnHandler; this._poolOfRecSendEventArgs.Push(eventArgObjectForPool); } //creation of the socker and binging to a listening port _listenSocket = new Socket(this._connectionendpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _listenSocket.Bind(this._connectionendpoint); _listenSocket.Listen(BACK_LOG); StartAccept(); }
public Int32 HandlePrefix(SocketAsyncEventArgs e, P2PPortClientConnectionHandler clientHandler, Int32 remainingBytesToProcess) { //receivedPrefixBytesDoneCount tells us how many prefix bytes were //processed during previous receive ops which contained data for //this message. Usually there will NOT have been any previous //receive ops here. So in that case, //receiveSendToken.receivedPrefixBytesDoneCount would equal 0. //Create a byte array to put the new prefix in, if we have not //already done it in a previous loop. if (clientHandler.receivedPrefixBytesDoneCount == 0) { clientHandler.byteArrayForPrefix = new Byte[clientHandler.receivePrefixLength]; } // If this next if-statement is true, then we have received >= // enough bytes to have the prefix. So we can determine the // length of the message that we are working on. if (remainingBytesToProcess >= clientHandler.receivePrefixLength - clientHandler.receivedPrefixBytesDoneCount) { //Now copy that many bytes to byteArrayForPrefix. //We can use the variable receiveMessageOffset as our main //index to show which index to get data from in the TCP //buffer. int srcOffset = clientHandler.receiveMessageOffset - clientHandler.receivePrefixLength + clientHandler.receivedPrefixBytesDoneCount; int count = clientHandler.receivePrefixLength - clientHandler.receivedPrefixBytesDoneCount; Buffer.BlockCopy(e.Buffer, srcOffset, clientHandler.byteArrayForPrefix, clientHandler.receivedPrefixBytesDoneCount, count); remainingBytesToProcess = remainingBytesToProcess - clientHandler.receivePrefixLength + clientHandler.receivedPrefixBytesDoneCount; clientHandler.recPrefixBytesDoneThisOp = clientHandler.receivePrefixLength - clientHandler.receivedPrefixBytesDoneCount; clientHandler.receivedPrefixBytesDoneCount = clientHandler.receivePrefixLength; clientHandler.lengthOfCurrentIncomingMessage = BitConverter.ToInt32(clientHandler.byteArrayForPrefix, 0); } else { //This next else-statement deals with the situation //where we have some bytes //of this prefix in this receive operation, but not all. //------------------- //Write the bytes to the array where we are putting the //prefix data, to save for the next loop. Buffer.BlockCopy(e.Buffer, clientHandler.receiveMessageOffset - clientHandler.receivePrefixLength + clientHandler.receivedPrefixBytesDoneCount, clientHandler.byteArrayForPrefix, clientHandler.receivedPrefixBytesDoneCount, remainingBytesToProcess); clientHandler.recPrefixBytesDoneThisOp = remainingBytesToProcess; clientHandler.receivedPrefixBytesDoneCount += remainingBytesToProcess; remainingBytesToProcess = 0; } // This section is needed when we have received // an amount of data exactly equal to the amount needed for the prefix, // but no more. And also needed with the situation where we have received // less than the amount of data needed for prefix. if (remainingBytesToProcess == 0) { clientHandler.receiveMessageOffset = clientHandler.receiveMessageOffset - clientHandler.recPrefixBytesDoneThisOp; clientHandler.recPrefixBytesDoneThisOp = 0; } return(remainingBytesToProcess); }
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs) { P2PPortClientConnectionHandler clientHandler = (P2PPortClientConnectionHandler)receiveSendEventArgs.UserToken; receiveSendEventArgs.SetBuffer(clientHandler.BufferOffsetReceive, P2PNetworkingDefinitions.DATABUFFER_SIZE); bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs); if (!willRaiseEvent) { ProcessReceive(receiveSendEventArgs); } }
private void ProcessReceive(SocketAsyncEventArgs receiveSendEventArgs) { P2PPortClientConnectionHandler clientHandler = (P2PPortClientConnectionHandler)receiveSendEventArgs.UserToken; if (receiveSendEventArgs.SocketError != SocketError.Success) { //--------------------------------------------------------- // at this point the client has disconnected unexpectedly clientHandler.Reset(); CloseClientSocket(receiveSendEventArgs); return; } if (receiveSendEventArgs.BytesTransferred == 0) { clientHandler.Reset(); CloseClientSocket(receiveSendEventArgs); return; } Int32 remainingBytesToProcess = receiveSendEventArgs.BytesTransferred; if (clientHandler.receivedPrefixBytesDoneCount < P2PNetworkingDefinitions.DATA_SEND_RECEIVE_PREFIX_LENGHT) { remainingBytesToProcess = _prefixHandler.HandlePrefix(receiveSendEventArgs, clientHandler, remainingBytesToProcess); if (remainingBytesToProcess == 0) { StartReceive(receiveSendEventArgs); return; } } bool incomingTcpMessageIsReady; incomingTcpMessageIsReady = this._messageHandler.HandleData(receiveSendEventArgs, clientHandler, remainingBytesToProcess); if (incomingTcpMessageIsReady != true) { clientHandler.receiveMessageOffset = clientHandler.BufferOffsetReceive; clientHandler.recPrefixBytesDoneThisOp = 0; StartReceive(receiveSendEventArgs); } else { //the data transmission is finished //the data is treated this.ProcessReceivedData(clientHandler); clientHandler.CreateNewDataReceivedBuffer(P2PNetworkingDefinitions.DATABUFFER_SIZE); clientHandler.Reset(); } }
/// <summary> /// prepares a data message to be sent to the P2P Port using the /// scheme of SocketAsyncEventArgs. the preparation consisits on /// arrange a byte where the first 4 bytes has the total lenght of /// packet and the rest is the data it self or part of if /// </summary> /// <param name="e"></param> /// <param name="data"></param> private static void PrepareAndBufferData(SocketAsyncEventArgs e, Byte[] data) { P2PPortClientConnectionHandler clientConnectionHandler = (P2PPortClientConnectionHandler)e.UserToken; Int32 lengthOfData = data.Length; Byte[] arrayOfBytesInPrefix = BitConverter.GetBytes(lengthOfData); int totalDataLenght = clientConnectionHandler.sendPrefixLength + lengthOfData; clientConnectionHandler.CreateNewDataToSendBuffer(totalDataLenght); //Now copy the 2 things to the theUserToken.dataToSend. Buffer.BlockCopy(arrayOfBytesInPrefix, 0, clientConnectionHandler.DataToSendBuffer, 0, clientConnectionHandler.sendPrefixLength); Buffer.BlockCopy(data, 0, clientConnectionHandler.DataToSendBuffer, clientConnectionHandler.sendPrefixLength, lengthOfData); clientConnectionHandler.sendBytesRemainingCount = clientConnectionHandler.sendPrefixLength + lengthOfData; clientConnectionHandler.bytesSentAlreadyCount = 0; }
private void StartSend(SocketAsyncEventArgs receiveSendEventArgs) { P2PPortClientConnectionHandler clientHandler = (P2PPortClientConnectionHandler)receiveSendEventArgs.UserToken; if (clientHandler.sendBytesRemainingCount <= P2PNetworkingDefinitions.DATABUFFER_SIZE) { receiveSendEventArgs.SetBuffer(clientHandler.BufferOffsetSend, clientHandler.sendBytesRemainingCount); //Copy the bytes to the buffer associated with this SAEA object. Buffer.BlockCopy(clientHandler.DataToSendBuffer, clientHandler.bytesSentAlreadyCount, receiveSendEventArgs.Buffer, clientHandler.BufferOffsetSend, clientHandler.sendBytesRemainingCount); } else { receiveSendEventArgs.SetBuffer(clientHandler.BufferOffsetSend, P2PNetworkingDefinitions.DATABUFFER_SIZE); Buffer.BlockCopy(clientHandler.DataToSendBuffer, clientHandler.bytesSentAlreadyCount, receiveSendEventArgs.Buffer, clientHandler.BufferOffsetSend, P2PNetworkingDefinitions.DATABUFFER_SIZE); } //post asynchronous send operation bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.SendAsync(receiveSendEventArgs); if (!willRaiseEvent) { ProcessSend(receiveSendEventArgs); } }
private void ProcessReceivedData(P2PPortClientConnectionHandler clientHandler) { /* * try * { * try * { * * Byte[] DataToDeserialize = ExtractP2PDataToDeserializeToP2PData(clientHandler.DataReceivedContainer.Data); * * //***************************************** * //tries to deserialize to a P2PDATA * //***************************************** * P2PData data = P2PData.Deserialize(DataToDeserialize); * this.Statistics.LogDataReceptionEvent(data); * try * { * //catches if an exception ocurrs to avoid the programm exist from the reading thread * //because of a failure in the object that implements the interface. * ((IUseP2PCommunicationsScheme)this._portOwnerComponent).ReceiveData(data, this.ListeningPortNumber); * Services.P2PCommunicationsScheme.Data.P2PDataDeliveryResult successfulDataDelivery = Services.P2PCommunicationsScheme.Data.P2PDataDeliveryResult.GetSucceedDeliveryResult(data); * * //prepares the data to be sent * * //clientHandler.CommunicationsSocket.Send(successfulDataDelivery.Serialize()); * //*************************************************************************************** * } * catch (Exception ex) * { * Services.P2PCommunicationsScheme.Data.P2PDataDeliveryResult failureDataDelivery = Services.P2PCommunicationsScheme.Data.P2PDataDeliveryResult.GetFailureDeliveryResult(data, ex.Message); * //prepates the data to be sent * clientHandler.CommunicationsSocket.Send(failureDataDelivery.Serialize()); * //*************************************************************************************** * } * } * catch (Exception ex) * { * //***************************************** * //tries to deserialize to a P2P_DATA_DELIVERY_RESULT * //***************************************** * P2PDataRequest dataRequest = default(P2PDataRequest); * P2PData dataRequested = default(P2PData); * try * { * //dataRequest = P2PDataRequest.Deserialize(client.ReceiveDataBuffer); * try * { * dataRequested = ((IUseP2PCommunicationsScheme)this._portOwnerComponent).RetrieveData(dataRequest, this.ListeningPortNumber); * if (!(dataRequested == null)) * { * this.Statistics.LogSuccesfulDataRequestEvent(dataRequest); * // client.handlerSocket.Send(dataRequested.Serialize()); * //*************************************************************************************** * } * else * { * this.Statistics.LogFailedDataRequestEvent(dataRequest); * string portOwnerName = ((IUseP2PCommunicationsScheme)this._portOwnerComponent).P2PPortOwnerName; * if (portOwnerName == null) * { * portOwnerName = "UNKNOWN"; * } * string errorMessage = "The remote object \'" + portOwnerName + "\' can\'t handle the requested data named \'" + dataRequest.RequestedDataName + "\'"; * P2PDataRequestFailure reqFAilure = P2PDataRequestFailure.GetP2PDataRequestFailure(dataRequest, errorMessage); * // client.handlerSocket.Send(reqFAilure.Serialize()); * //*************************************************************************************** * * } * } * catch (Exception ex2) * { * this.Statistics.LogFailedDataRequestEvent(dataRequest); * string portOwnerName = ((IUseP2PCommunicationsScheme)this._portOwnerComponent).P2PPortOwnerName; * if (portOwnerName == null) * { * portOwnerName = "UNKNOWN"; * } * string errorMessage = ex2.Message; * P2PDataRequestFailure reqFAilure = P2PDataRequestFailure.GetP2PDataRequestFailure(dataRequest, errorMessage); * // client.handlerSocket.Send(reqFAilure.Serialize()); * //*************************************************************************************** * } * } * catch (Exception) * { * string msg = ""; * msg = "Error processing incomming data from P2PPort client : " + ex.ToString(); * CustomEventLog.WriteEntry(EventLogEntryType.Error, msg); * } * } * } * catch (Exception ex) * { * string msg = ""; * msg = "Error processing incomming data from P2PPort client : " + ex.ToString(); * CustomEventLog.WriteEntry(EventLogEntryType.Error, msg); * } */ }