/* * Core methods of Disquuun. */ /** * method for Sync execution of specific Disque command. * DEPRECATED. only use for testing. */ public override DisquuunResult[] DEPRECATED_Sync(DisqueCommand command, byte[] data) { #if LOGIC_BENCH { socketToken.socketState = SocketState.OPENED; return(new DisquuunResult[0]); } #endif try { socketToken.socket.Send(data); var currentLength = 0; var scanResult = new DisquuunAPI.ScanResult(false); while (true) { // waiting for head of transferring data or rest of data. socketToken.socket.Receive(socketToken.receiveBuffer, currentLength, 1, SocketFlags.None); currentLength = currentLength + 1; var available = socketToken.socket.Available; var readableLength = currentLength + available; { if (socketToken.receiveBuffer.Length < readableLength) { Array.Resize(ref socketToken.receiveBuffer, readableLength); } } // read rest. socketToken.socket.Receive(socketToken.receiveBuffer, currentLength, available, SocketFlags.None); currentLength = currentLength + available; scanResult = DisquuunAPI.ScanBuffer(command, socketToken.receiveBuffer, 0, currentLength, socketId); if (scanResult.isDone) { break; } // continue reading data from socket. // if need, prepare for next 1 byte. if (socketToken.receiveBuffer.Length == readableLength) { Array.Resize(ref socketToken.receiveBuffer, socketToken.receiveBuffer.Length + 1); } } socketToken.socketState = SocketState.OPENED; return(scanResult.data); } catch (Exception e) { throw e; } }
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 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 OnReceived(object unused, SocketAsyncEventArgs args) { var token = (SocketToken)args.UserToken; if (args.SocketError != SocketError.Success) { switch (token.socketState) { case SocketState.CLOSING: case SocketState.CLOSED: { // already closing, ignore. return; } default: { switch (args.SocketError) { case SocketError.ConnectionReset: { Disquuun.Log("ConnectionResetが出てる. " + " token.socketState:" + token.socketState, true); break; } default: { Disquuun.Log("onReceive default token.socketState:" + token.socketState + " error:" + args.SocketError, true); break; } } Disconnect(); var e1 = new Exception("receive status is not good."); SocketClosed(this, "failed to receive.", e1); return; } } } if (args.BytesTransferred == 0) { return; } var bytesAmount = args.BytesTransferred; // update as read completed. token.readableDataLength = token.readableDataLength + bytesAmount; var result = DisquuunAPI.ScanBuffer(token.currentCommand, token.receiveBuffer, token.readableDataLength, socketId); // data is totally read and executable. if (result.cursor == token.readableDataLength) { var continuation = token.AsyncCallback(token.currentCommand, result.data); // update continuation status. token.continuation = continuation; if (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 { 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. /* * note that, * * SetBuffer([buffer], offset, count)'s "count" is, actually not count. * * it's "offset" is "offset of receiving-data-window against buffer", * but the "count" is actually "size limitation of next receivable data size". * * this "size" should be smaller than size of current bufferSize - offset && larger than 0. * * e.g. * if buffer is buffer[10], offset can set 0 ~ 8, and, * count should be 9 ~ 1. * * if vaiolate to this rule, ReceiveAsync never receive data. not good behaviour. * * and, the "buffer" is treated as pointer. this API treats the pointer of buffer directly. * this means, when the byteTransferred is reaching to the size of "buffer", then you resize it to proper size, * * you should re-set the buffer's pointer by using SetBuffer API. * * * actually, SetBuffer's parameters are below. * * socket.SetBuffer([bufferAsPointer], additionalDataOffset, receiveSizeLimit) */ var nextAdditionalBytesLength = token.socket.Available; if (token.readableDataLength == token.receiveBuffer.Length) { Array.Resize(ref token.receiveBuffer, token.receiveArgs.Buffer.Length + nextAdditionalBytesLength); } var receivableCount = token.receiveBuffer.Length - token.readableDataLength; token.receiveArgs.SetBuffer(token.receiveBuffer, token.readableDataLength, receivableCount); if (!token.socket.ReceiveAsync(token.receiveArgs)) { OnReceived(token.socket, token.receiveArgs); } }