Execution of an exe consuming WCF Service is failing inside windows docker container

Hi All,

I am facing an issue in implementation of one task and not getting enough support from within my org as they do not have much expertise on the .net side of docker implementation.

This is a sample application and scenario just for the purpose of replicating the issue and the actual implementation is with adhering to all standards.

I have a console application written in .NET framework 4.8. It consumes a .NET WCF web service with the help of a proxy at a given port 18793 which is hosted on the local machine (its my laptop in this illustrated example) as a console host service. The web service uses net.Tcp binding protocol. Details of the architecture in brief is as below -

Service Contract (POSTest) :-

using System.ServiceModel;

namespace PosTest
{
    [ServiceContract]
    public interface IPosTestSvc
    {
        [OperationContract]
        string GetData(int value);
    }
}

Service Implementation :-

using System.ServiceModel;

namespace PosTest
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class PosTestSvc : IPosTestSvc
    {
        public string GetData(int value)
        {
            return $"GetData Service method called with value {value}";
        }
    }
}

Proxy for the Service where WebReference to the hosted service is added :-

using PosTest.Proxy.WcfSvcRef;
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace PosTest.Proxy
{
    public class PosDeploymentDefaultProxy
    {
        public int ClientDataValue { get; set; }
        public string GetData
        {
            get
            {
                var binding = GetEndPointBinding();
                var address = new EndpointAddress(new Uri("net.tcp://mylenovo:18793/PostTest/DeploymentDefault"), EndpointIdentity.CreateSpnIdentity(""));
                IPosTestSvcChannel client = ChannelFactory<IPosTestSvcChannel>.CreateChannel(binding,address);
                return client.GetData(ClientDataValue);
            }
        }

        private static Binding GetEndPointBinding()
        {
            Binding binding = new NetTcpBinding();
            ((NetTcpBinding)binding).MaxReceivedMessageSize = 2147483647;
            ((NetTcpBinding)binding).MaxBufferSize = 2147483647;
            ((NetTcpBinding)binding).MaxBufferPoolSize = 2147483647;

            binding.SendTimeout = new TimeSpan(0, 120, 0);
            binding.ReceiveTimeout = new TimeSpan(0, 120, 0);
            return binding;
        }
    }
}

Finally the above Proxy is used as a reference to the client console app :-

using PosTest.Proxy;
using System;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices;
using System.Linq;

namespace PosTest.Client
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"Testing WCF Service....");
            Console.WriteLine($"{UserPrincipal.Current.UserPrincipalName}");

            var c = new PosDeploymentDefaultProxy();
            string x = "";
            if (args.Count() == 0)
            {
                x = "0";
            }
            else
            {
                x = args[0];
            }
            c.ClientDataValue = Convert.ToInt32(x);
            Console.WriteLine(c.GetData);
        }
    }
}

When this console app is executed within the windows docker container created out of the image: mcr.microsoft.com/dotnet/framework/sdk:4.8.1 where I am manually copying the “POSTestClient” exe binaries into the container and executing the exe as below in powershell :-

cmd /c PosTest.Client.exe 7843

then I get the following error in the windows docker container :-

PS C\POS\PosTestClient> cmd /c PosTest.Client.exe

Unhandled Exception System.ServiceModel.CommunicationException The socket connection was aborted. 
This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. 
Local socket timeout was '015953.5154850'. ---> System.IO.IOException 
The write operation failed, see inner exception. ---> System.ServiceModel.CommunicationException The socket connection was aborted. 
This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. 
Local socket timeout was '015953.5154850'. ---> System.Net.Sockets.SocketException An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.ServiceModel.Channels.SocketConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Channels.SocketConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
   at System.ServiceModel.Channels.BufferedConnection.WriteNow(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, BufferManager bufferManager)
   at System.ServiceModel.Channels.BufferedConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
   at System.ServiceModel.Channels.ConnectionStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.NegotiateStream.StartWriting(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   --- End of inner exception stack trace ---
   at System.Net.Security.NegotiateStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
   --- End of inner exception stack trace ---

Server stack trace
   at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment1 preamble, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
   at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at PostTest.Proxy.WcfSvcRef.IPosTestSvc.GetData(Int32 value)
   at PostTest.Proxy.PosDeploymentDefaultProxy.get_GetData() in D\Project\WCfMyLocalService\PostTest.Proxy\PosDeploymentDefaultProxy.csline 18
   at PosTest.Client.Program.Main(String[] args) in D\Project\WCfMyLocalService\PosTest.Client\Program.csline 22

I tried to check whether the host is getting resolved by using svcutil command

svcutil net.tcp://mylenovo:18794/PostTest/mex

and downloading the metadata

which returned me no error.

It downloaded the metadata and generating output :-

Attempting to download metadata from 'net.tcp://mylenovo:18794/PostTest/mex' using WS-Metadata Exchange.

This URL does not support DISCO.

Generating files... C:\POS\PosTestClient\PosTestSvc.cs C:\POS\PosTestClient\output.config  

After the above it can be assumed that the windows docker container is able to resolve the host. But what I am not able to understand is why the console app is crashing at the time of connecting to the service.

Could you please help here ?

Thanks
Shobhit

What is “mylenovo”? Is it a domain name registered in a DNS server or something in a hosts file? I have no idea how the .NET part works, but if that uses a DNS server and ignores the hosts file while svcutil uses the hosts file, the .NET console app could crash. Have you tried it with an IP address?

“mylenovo” is my laptop name. As I am trying this illustration on my personal laptop. But in real scenario in my organization it is a domain name. I am not sure though whether that is registered in hosts file. But I am able to replicate the same behavior on my personal laptop.

And yes, it gives the same error when I am trying with the ip address. The host when test with the below command also gives output which shows that the container is able to resolve the host name and port unless this is misleading.

PS C:\POS\PosTestClient> tnc MYLENOVO -port 18793

ComputerName     : MYLENOVO
RemoteAddress    : <ipv6 adrs> (this is a IPv6 Address and not IPv4 ,Is that a concern ?)
RemotePort       : 18793
InterfaceAlias   : Ethernet
SourceAddress    : <ipv6 adrs e.g. d7b5:7b3d:blah>
TcpTestSucceeded : True

I also tried to hit the application when the service is down, then the error changes, it is below -

Unhandled Exception: System.ServiceModel.EndpointNotFoundException: Could not connect to net.tcp://mylenovo:18793/PostTest/DeploymentDefault. The connection attempt lasted for a time span of 00:00:42.0155729. TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 172.17.160.1:18793.  ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 172.17.160.1:18793
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri uri, TimeSpan timeout)
   --- End of inner exception stack trace ---