Inside the Standard Bindings: NetTcp

Index for bindings in this series:

Today continues the series I started last week about the standard bindings. The previous article covered the BasicHttp binding. Today's article covers the NetTcp binding, which is going to be the popular out-of-the-box choice for communicating over an Intranet. The default configuration for TCP is faster than the configuration for HTTP, but intended only for WCF-to-WCF communication. You can open that up with a cost to speed, and you can add some WS-* specification features again at a cost to speed. There's more about this in the article I did for choosing transports and message encoders. Whereas the HTTP bindings tend to turn things on by default, the TCP binding tends to turn things off by default so that you have to opt-in.

I'm again going to use the Security.Mode settings on the binding as my primary pivot for talking about the binding elements that are produced by the binding. The available settings are no security, TCP/SSL security, SOAP security, and TCP/SSL security with SOAP credentials. Let me repeat the presentation disclaimer I used previously because it applies just the same this time.

I've cut down on the number of properties presented by eliminating duplicates between the binding settings and binding element settings. For instance, the XML reader quotas can be set on either the binding or the message encoder binding element, but I'm only going to show them on the message encoder. I've also omitted most of the security credential settings because they're very messy and you hopefully won't need to change them much.

When Security.Mode is set to None, there are three binding elements in the channel stack.

  1. System.ServiceModel.Channels.TransactionFlowBindingElement

     TransactionProtocol: OleTransactions
    
  2. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement

     AddressingVersion: Addressing10 (https://www.w3.org/2005/08/addressing)
    MaxReadPoolSize: 64
    MaxSessionSize: 2048
    MaxWritePoolSize: 16
    ReaderQuotas: 
      MaxArrayLength: 16384
      MaxBytesPerRead: 4096
      MaxDepth: 32
      MaxNameTableCharCount: 16384
      MaxStringContentLength: 8192
    
  3. System.ServiceModel.Channels.TcpTransportBindingElement

     ConnectionBufferSize: 8192
    ConnectionLeaseTimeout: 00:05:00
    ConnectionPoolGroupName: default
    HostNameComparisonMode: StrongWildcard
    IdleTimeout: 00:02:00
    ListenBacklog: 10
    ManualAddressing: False
    MaxBufferPoolSize: 524288
    MaxBufferSize: 65536
    MaxInboundConnections: 10
    MaxOutboundConnectionsPerEndpoint: 10
    MaxOutputDelay: 00:00:00.2000000
    MaxPendingAccepts: 1
    MaxReceivedMessageSize: 65536
    PortSharingEnabled: False
    Scheme: net.tcp
    TeredoEnabled: False
    TransferMode: Buffered
    

And there are a number of loose settings on the binding not otherwise covered by these elements.

 CloseTimeout: 00:01:00
EnvelopeVersion: Soap12 (https://www.w3.org/2003/05/soap-envelope)
MaxConnections: 10
Namespace: https://tempuri.org/
OpenTimeout: 00:01:00
ReceiveTimeout: 00:01:00
ReliableSession: 
  Enabled: False
SendTimeout: 00:01:00
TransactionFlow: False

These are the baseline settings and all of the variations are very similar so I'm not going to repeat the properties unless they're new or different.

Enabling Transport security adds a new binding element to perform the transform on the data stream. Note that unlike HTTP, the transport itself does not change and we do not integrate the transport security binding element with the transport binding element.

  1. System.ServiceModel.Channels.TransactionFlowBindingElement

  2. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement

  3. System.ServiceModel.Channels.WindowsStreamSecurityBindingElement

     ProtectionLevel: EncryptAndSign
    
  4. System.ServiceModel.Channels.TcpTransportBindingElement

Setting Security.Mode to either Message or TransportWithMessageCredentials works almost the same as it did for HTTP. We take the channel stack corresponding to a Security.Mode of either None or Transport and add an additional binding element to perform SOAP security. The specific binding element used for security varies depending on both the Security.Mode setting and the security options that are being used.

Here's an example with Security.Mode set to Message:

  1. System.ServiceModel.Channels.TransactionFlowBindingElement
  2. System.ServiceModel.Channels.SymmetricSecurityBindingElement
  3. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
  4. System.ServiceModel.Channels.TcpTransportBindingElement

And here's an example with Security.Mode set to TransportWithMessageCredentials:

  1. System.ServiceModel.Channels.TransactionFlowBindingElement

  2. System.ServiceModel.Channels.TransportSecurityBindingElement

  3. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement

  4. System.ServiceModel.Channels.SslStreamSecurityBindingElement

     RequireClientCertificate: False
    
  5. System.ServiceModel.Channels.TcpTransportBindingElement

Note that in all of these channel stacks, the transactions binding element was included even though transactions are disabled by default. The same is not true for reliable messaging. A binding element only appears for reliable messaging if you specifically enable that feature by setting the ReliableSession property to true.

  1. System.ServiceModel.Channels.TransactionFlowBindingElement

  2. System.ServiceModel.Channels.ReliableSessionBindingElement

     AcknowledgementInterval: 00:00:00.2000000
    EnableFlowControl: True
    InactivityTimeout: 00:10:00
    MaxPendingChannels: 128
    MaxRetryCount: 8
    MaxTransferWindowSize: 32
    Ordered: True
    
  3. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement

  4. System.ServiceModel.Channels.TcpTransportBindingElement

I used Security.Mode set to None for this example, but reliable messaging works with other security modes as well.

Next time: Inside the Standard Bindings: NetNamedPipe