/// <summary> /// Handle a new connection on the server stream. End the waitfor connection and restart waiting on a new serverstream. /// </summary> /// <param name="iAsyncResult"></param> private void _pipeConnected(IAsyncResult iAsyncResult) { //Get the connecting client from the asyncstate and end the connection process AsyncPipeStateWrapper wrapper = iAsyncResult.AsyncState as AsyncPipeStateWrapper; NamedPipeServerStream connectingClient = wrapper.NamedPipeServerStream; connectingClient.EndWaitForConnection(iAsyncResult); //Double-check the damn connection is actually connected if (connectingClient.IsConnected) { //Lock the connecting client and start a read on it byte[] readBuffer = new byte[SIZE_BUFFER]; lock (connectingClient) { connectingClient.BeginRead(readBuffer, 0, SIZE_BUFFER, new AsyncCallback(_endRead), new AsyncPipeStateWrapper(connectingClient, readBuffer)); } //The namedPipeServerStream BECOMES the connection object after it connects. //Lock the list to avoid thread issues lock (_connectedPipeStreams) { _connectedPipeStreams.Add(connectingClient); } } //Restart the pipe waiting for connection NamedPipeServerStream newConnection = new NamedPipeServerStream(SB_PIPE_NAME, PipeDirection.InOut, -1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); newConnection.BeginWaitForConnection(new AsyncCallback(this._pipeConnected), new AsyncPipeStateWrapper(newConnection, null)); }
/// <summary> /// End an asynchronous write operation and flush the stream written to. /// </summary> /// <param name="iAsyncResult"></param> private void _endWrite(IAsyncResult iAsyncResult) { AsyncPipeStateWrapper wrapper = iAsyncResult.AsyncState as AsyncPipeStateWrapper; NamedPipeServerStream connection = wrapper.NamedPipeServerStream; //Lock on the connection lock (connection) { //End the write operation and flush. connection.EndWrite(iAsyncResult); connection.Flush(); } }
/// <summary> /// End the asynchronous read operation on a connected named pipe. /// </summary> /// <param name="iAsyncResult"></param> private void _endRead(IAsyncResult iAsyncResult) { //Get the instance of the connection we're ending for AsyncPipeStateWrapper wrapper = iAsyncResult.AsyncState as AsyncPipeStateWrapper; NamedPipeServerStream connection = wrapper.NamedPipeServerStream; if (connection != null && connection.IsConnected) { try { //Get the length read int length = connection.EndRead(iAsyncResult); byte[] readBuffer = wrapper.Buffer; //If we have somethign read... if (length > 0) { byte[] destinationArray = new byte[length]; Array.Copy(readBuffer, 0, destinationArray, 0, length); //Deserialize the read object using (MemoryStream memStream = new MemoryStream(readBuffer)) { //Still figuring out why this excepts try { SbStateObject stateObject = Serializer.Deserialize <SbStateObject>(memStream); //Cool, we have ourselves our very own SbStateObject. Fire the event. if (SbStateObjectReceived != null) { SbStateObjectReceived(this, new SbStateObjectEventArgs(stateObject, connection)); } } catch (ProtoException) { } } } //lock the connection and begin reading lock (connection) { //Sanitize the read buffer. FFS, examples... readBuffer = new byte[SIZE_BUFFER]; connection.BeginRead(readBuffer, 0, SIZE_BUFFER, new AsyncCallback(this._endRead), new AsyncPipeStateWrapper(connection, readBuffer)); } } catch (Exception) { } } }