private void PipelineReceive(SocketToken token) { var fromCursor = 0; /* * read data from receiveBuffer by moving fromCursor. */ while (true) { var currentCommand = token.currentCommands.Peek(); var result = DisquuunAPI.ScanBuffer(currentCommand, token.receiveBuffer, fromCursor, token.readableDataLength, socketId); if (result.isDone) { token.AsyncCallback(currentCommand, result.data); // deque as read done. token.currentCommands.Dequeue(); if (token.currentCommands.Count == 0) { // pipelining is over. switch (token.socketState) { case SocketState.BUSY: { token.socketState = SocketState.RECEIVED; break; } case SocketState.SENDED: { token.socketState = SocketState.OPENED; SocketReloaded(this); break; } default: { break; } } return; } // commands are still remained. // got all data is just consumed. get rest from outside. if (fromCursor == token.readableDataLength) { StartContinueReceiving(token, 0); return; } // rest pipeline commands and received data is exists in buffer. fromCursor = result.cursor; continue; } /* * reading is not completed. the fragment of command exists. */ var fragmentDataLength = token.readableDataLength - fromCursor; // move fragment data to head of buffer. Buffer.BlockCopy(token.receiveBuffer, fromCursor, token.receiveBuffer, 0, fragmentDataLength); StartContinueReceiving(token, fragmentDataLength); break; } }
private void LoopOrAsyncReceive(SocketToken token) { var currentCommand = token.currentCommands.Peek(); var result = DisquuunAPI.ScanBuffer(currentCommand, token.receiveBuffer, 0, token.readableDataLength, socketId); if (result.isDone && result.cursor == token.readableDataLength) { // update continuation status. token.continuation = token.AsyncCallback(currentCommand, result.data); if (token.continuation) { switch (token.socketState) { case SocketState.BUSY: { token.socketState = SocketState.RECEIVED; break; } case SocketState.SENDED: { // ready for next loop receive. token.readableDataLength = 0; token.receiveArgs.SetBuffer(token.receiveBuffer, 0, token.receiveBuffer.Length); if (!token.socket.ReceiveAsync(token.receiveArgs)) { OnReceived(token.socket, token.receiveArgs); } try { token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length); } catch { // renew. potential error is exists and should avoid this error. var sendArgs = new SocketAsyncEventArgs(); sendArgs.RemoteEndPoint = token.receiveArgs.RemoteEndPoint; sendArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnSend); sendArgs.UserToken = token; token.sendArgs = sendArgs; token.sendArgs.SetBuffer(token.currentSendingBytes, 0, token.currentSendingBytes.Length); } if (!token.socket.SendAsync(token.sendArgs)) { OnSend(token.socket, token.sendArgs); } break; } default: { // closing or other state. should close. break; } } return; } // end of loop or end of async. switch (token.socketState) { case SocketState.BUSY: { token.socketState = SocketState.RECEIVED; break; } case SocketState.SENDED: { token.socketState = SocketState.OPENED; SocketReloaded(this); break; } default: { break; } } return; } // not yet received all data. // continue receiving. StartContinueReceiving(token, token.readableDataLength); }
private void StartReceiveAndSendDataAsync(DisqueCommand[] commands, byte[] data, Func <DisqueCommand, DisquuunResult[], bool> Callback) { #if LOGIC_BENCH { socketToken.currentCommands = commands; socketToken.currentSendingBytes = data; socketToken.AsyncCallback = Callback; socketToken.isPipeline = false; if (1 < commands.Length) { socketToken.isPipeline = true; pipelineIndex = 0; // -> PipelineReceive(token); { foreach (var command in commands) { var result = new DisquuunResult[0]; socketToken.AsyncCallback(command, result); } socketToken.socketState = SocketState.OPENED; SocketReloaded(this); } } else { // OnSend -> token.socketState = SocketState.SENDED; // receive -> Bench_LoopOrAsyncReceive(token); { Bench_LoopOrAsyncReceive(commands[0]); } } return; } #endif // ready for receive. socketToken.readableDataLength = 0; socketToken.receiveArgs.SetBuffer(socketToken.receiveBuffer, 0, socketToken.receiveBuffer.Length); if (!socketToken.socket.ReceiveAsync(socketToken.receiveArgs)) { OnReceived(socketToken.socket, socketToken.receiveArgs); } // if multiple commands exist, set as pipeline. socketToken.isPipeline = false; if (1 < commands.Length) { socketToken.isPipeline = true; pipelineIndex = 0; } socketToken.currentCommands = commands; socketToken.currentSendingBytes = data; socketToken.AsyncCallback = Callback; try { socketToken.sendArgs.SetBuffer(data, 0, data.Length); } catch { // renew. potential error is exists and should avoid this error. var sendArgs = new SocketAsyncEventArgs(); sendArgs.RemoteEndPoint = socketToken.receiveArgs.RemoteEndPoint; sendArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnSend); sendArgs.UserToken = socketToken; socketToken.sendArgs = sendArgs; socketToken.sendArgs.SetBuffer(data, 0, data.Length); } if (!socketToken.socket.SendAsync(socketToken.sendArgs)) { OnSend(socketToken.socket, socketToken.sendArgs); } }