Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Remoting / Channels / TCP / TcpSocketManager.cs / 1305376 / TcpSocketManager.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //========================================================================== // File: TcpSocketManager.cs // // Summary: Provides a base for the client and server tcp socket // managers. // //========================================================================= using System; using System.Collections; using System.Globalization; using System.IO; using System.Net; using System.Net.Sockets; using System.Runtime.Remoting.Messaging; using System.Text; using System.Threading; namespace System.Runtime.Remoting.Channels.Tcp { // A client socket manager instance should encapsulate the socket // for the purpose of reading a response internal abstract class TcpSocketHandler : SocketHandler { private static byte[] s_protocolPreamble = Encoding.ASCII.GetBytes(".NET"); private static byte[] s_protocolVersion1_0 = new byte[]{1,0}; public TcpSocketHandler(Socket socket, Stream stream) : this(socket, null, stream) { } // TcpSocketHandler public TcpSocketHandler(Socket socket, RequestQueue requestQueue, Stream stream) : base(socket, requestQueue, stream) { } // TcpSocketHandler private void ReadAndMatchPreamble() { // make sure that the incoming data starts with the preamble InternalRemotingServices.RemotingAssert( s_protocolPreamble.Length == 4, "The preamble is supposed to be 4 bytes ('.NET'). Somebody changed it..."); if (ReadAndMatchFourBytes(s_protocolPreamble) == false) { throw new RemotingException( CoreChannel.GetResourceString("Remoting_Tcp_ExpectingPreamble")); } } // ReadAndMatchPreamble protected void WritePreambleAndVersion(Stream outputStream) { outputStream.Write(s_protocolPreamble, 0, s_protocolPreamble.Length); outputStream.Write(s_protocolVersion1_0, 0, s_protocolVersion1_0.Length); } // WritePreamble protected void ReadVersionAndOperation(out UInt16 operation) { // check for the preamble ReadAndMatchPreamble(); // Check the version number. byte majorVersion = (byte)ReadByte(); byte minorVersion = (byte)ReadByte(); if ((majorVersion != 1) || (minorVersion != 0)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_UnknownProtocolVersion"), majorVersion.ToString(CultureInfo.CurrentCulture) + "." + minorVersion.ToString(CultureInfo.CurrentCulture))); } // Read the operation operation = ReadUInt16(); } // ReadVersionAndOperation protected void ReadContentLength(out bool chunked, out int contentLength) { contentLength = -1; UInt16 header = ReadUInt16(); if (header == TcpContentDelimiter.Chunked) { chunked = true; } else if (header == TcpContentDelimiter.ContentLength) { chunked = false; contentLength = ReadInt32(); } else { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_ExpectingContentLengthHeader"), header.ToString(CultureInfo.CurrentCulture))); } } // ReadContentLength protected void ReadToEndOfHeaders(BaseTransportHeaders headers) { bool bError = false; String statusPhrase = null; UInt16 headerType = ReadUInt16(); while (headerType != TcpHeaders.EndOfHeaders) { if (headerType == TcpHeaders.Custom) { String headerName = ReadCountedString(); String headerValue = ReadCountedString(); headers[headerName] = headerValue; } else if (headerType == TcpHeaders.RequestUri) { ReadAndVerifyHeaderFormat("RequestUri", TcpHeaderFormat.CountedString); // read uri (and make sure that no channel specific data is present) String uri = ReadCountedString(); String channelURI; String objectURI; channelURI = TcpChannelHelper.ParseURL(uri, out objectURI); if (channelURI == null) objectURI = uri; headers.RequestUri = objectURI; } else if (headerType == TcpHeaders.StatusCode) { ReadAndVerifyHeaderFormat("StatusCode", TcpHeaderFormat.UInt16); UInt16 statusCode = ReadUInt16(); // We'll throw an exception here if there was an error. If an error // occurs above the transport level, the status code will still be // success here. if (statusCode != TcpStatusCode.Success) bError = true; } else if (headerType == TcpHeaders.StatusPhrase) { ReadAndVerifyHeaderFormat("StatusPhrase", TcpHeaderFormat.CountedString); statusPhrase = ReadCountedString(); } else if (headerType == TcpHeaders.ContentType) { ReadAndVerifyHeaderFormat("Content-Type", TcpHeaderFormat.CountedString); String contentType = ReadCountedString(); headers.ContentType = contentType; } else { // unknown header: Read header format and ignore rest of data byte headerFormat = (byte)ReadByte(); switch (headerFormat) { case TcpHeaderFormat.Void: break; case TcpHeaderFormat.CountedString: ReadCountedString(); break; case TcpHeaderFormat.Byte: ReadByte(); break; case TcpHeaderFormat.UInt16: ReadUInt16(); break; case TcpHeaderFormat.Int32: ReadInt32(); break; default: { // unknown format throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_UnknownHeaderType"), headerType, headerFormat)); } } // switch (format) } // read next header token headerType = ReadUInt16(); } // loop until end of headers // if an error occurred, throw an exception if (bError) { if (statusPhrase == null) statusPhrase = ""; throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_GenericServerError"), statusPhrase)); } } // ReadToEndOfHeaders protected void WriteHeaders(ITransportHeaders headers, Stream outputStream) { IEnumerator it = null; BaseTransportHeaders wkHeaders = headers as BaseTransportHeaders; if (wkHeaders != null) { // write out well known headers // NOTE: RequestUri is written out elsewhere. if (wkHeaders.ContentType != null) { WriteContentTypeHeader(wkHeaders.ContentType, outputStream); } it = wkHeaders.GetOtherHeadersEnumerator(); } else { it = headers.GetEnumerator(); } // write custom headers if (it != null) { while (it.MoveNext()) { DictionaryEntry header = (DictionaryEntry)it.Current; String headerName = (String)header.Key; if (!StringHelper.StartsWithDoubleUnderscore(headerName)) // exclude special headers { String headerValue = header.Value.ToString(); if (wkHeaders == null) { if (String.Compare(headerName, "Content-Type", StringComparison.OrdinalIgnoreCase) == 0) { WriteContentTypeHeader(headerValue, outputStream); continue; } } WriteCustomHeader(headerName, headerValue, outputStream); } } // while (it.MoveNext()) } // write EndOfHeaders token WriteUInt16(TcpHeaders.EndOfHeaders, outputStream); } // WriteHeaders private void WriteContentTypeHeader(String value, Stream outputStream) { WriteUInt16(TcpHeaders.ContentType, outputStream); WriteByte(TcpHeaderFormat.CountedString, outputStream); WriteCountedString(value, outputStream); } // WriteContentTypeHeader private void WriteCustomHeader(String name, String value, Stream outputStream) { WriteUInt16(TcpHeaders.Custom, outputStream); WriteCountedString(name, outputStream); WriteCountedString(value, outputStream); } // WriteCustomHeader protected String ReadCountedString() { // strings are formatted as follows // [string format (1-byte)][encoded-size (int32)][string value (encoded-size length in bytes)] byte strFormat = (byte)ReadByte(); int strDataSize = ReadInt32(); if (strDataSize > 0) { byte[] data = new byte[strDataSize]; // SocketHander::Read waits until it reads all requested data Read(data, 0, strDataSize); switch (strFormat) { case TcpStringFormat.Unicode: return Encoding.Unicode.GetString(data); case TcpStringFormat.UTF8: return Encoding.UTF8.GetString(data); default: throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_UnrecognizedStringFormat"), strFormat.ToString(CultureInfo.CurrentCulture))); } } else { return null; } } // ReadCountedString protected void WriteCountedString(String str, Stream outputStream) { // strings are formatted as follows [string length (int32)][string value (unicode)] int strLength = 0; if (str != null) strLength = str.Length; if (strLength > 0) { byte[] strBytes = Encoding.UTF8.GetBytes(str); // write string format WriteByte(TcpStringFormat.UTF8, outputStream); // write string data size WriteInt32(strBytes.Length, outputStream); // write string data outputStream.Write(strBytes, 0, strBytes.Length); } else { // write string format // (just call it Unicode (doesn't matter since there is no data)) WriteByte(TcpStringFormat.Unicode, outputStream); // stream data size is 0. WriteInt32(0, outputStream); } } // WriteCountedString private void ReadAndVerifyHeaderFormat(String headerName, byte expectedFormat) { byte headerFormat = (byte)ReadByte(); if (headerFormat != expectedFormat) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Tcp_IncorrectHeaderFormat"), expectedFormat, headerName)); } } // ReadAndVerifyHeaderFormat } // TcpSocketHandler } // namespace System.Runtime.Remoting.Channels // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BitVector32.cs
- WindowsFormsHelpers.cs
- XmlNamespaceMappingCollection.cs
- HttpResponseInternalWrapper.cs
- NavigationPropertySingletonExpression.cs
- TraceSwitch.cs
- DesignerActionList.cs
- CalendarSelectionChangedEventArgs.cs
- XPathScanner.cs
- DesignerTransactionCloseEvent.cs
- BitmapDownload.cs
- AbsoluteQuery.cs
- GridItem.cs
- TemplateBindingExtension.cs
- ThousandthOfEmRealPoints.cs
- ResourceExpressionBuilder.cs
- WSSecurityPolicy12.cs
- SiteIdentityPermission.cs
- ToolBarPanel.cs
- CriticalFinalizerObject.cs
- UIElementParaClient.cs
- ColorAnimationBase.cs
- TextElementEnumerator.cs
- CrossContextChannel.cs
- DbProviderFactory.cs
- FontDifferentiator.cs
- SerializationObjectManager.cs
- UserControlParser.cs
- RtfControlWordInfo.cs
- Simplifier.cs
- EventArgs.cs
- InternalConfigSettingsFactory.cs
- Padding.cs
- XmlIlGenerator.cs
- UserControl.cs
- DeviceContext2.cs
- ApplicationId.cs
- Compilation.cs
- SortedDictionary.cs
- webclient.cs
- RepeatBehavior.cs
- ImageCodecInfo.cs
- Stack.cs
- CodeIdentifiers.cs
- Select.cs
- ConfigXmlWhitespace.cs
- ExtendedPropertyInfo.cs
- UpdatePanel.cs
- InternalDuplexChannelFactory.cs
- DefaultIfEmptyQueryOperator.cs
- ConnectionString.cs
- InputBindingCollection.cs
- FillRuleValidation.cs
- RubberbandSelector.cs
- SessionStateUtil.cs
- DisplayInformation.cs
- NestedContainer.cs
- Mouse.cs
- ErrorFormatterPage.cs
- MetadataPropertyCollection.cs
- PeerHelpers.cs
- AttachedAnnotation.cs
- ADConnectionHelper.cs
- wmiprovider.cs
- ComMethodElementCollection.cs
- BindingGraph.cs
- SecondaryIndexDefinition.cs
- HtmlInputCheckBox.cs
- PageThemeBuildProvider.cs
- _SpnDictionary.cs
- WorkflowService.cs
- CredentialCache.cs
- Attributes.cs
- ColorTransform.cs
- ProtocolState.cs
- XmlFormatExtensionAttribute.cs
- ContentPosition.cs
- SmiTypedGetterSetter.cs
- DocumentScope.cs
- Brushes.cs
- WorkflowPersistenceService.cs
- BatchStream.cs
- _Events.cs
- WebCategoryAttribute.cs
- RtfToXamlReader.cs
- PackageStore.cs
- SecurityPermission.cs
- ProfessionalColorTable.cs
- ExtendedProperty.cs
- InfoCardTrace.cs
- HTMLTagNameToTypeMapper.cs
- RecommendedAsConfigurableAttribute.cs
- CanonicalXml.cs
- Transform.cs
- DesignerCategoryAttribute.cs
- CustomAttribute.cs
- Substitution.cs
- WebResourceAttribute.cs
- OracleParameterBinding.cs
- SelectedGridItemChangedEvent.cs