microsoft / mindaro

Bridge to Kubernetes - for Visual Studio and Visual Studio Code
MIT License
307 stars 106 forks source link

System.Net.Sockets not working #233

Closed SteveCurran closed 2 years ago

SteveCurran commented 2 years ago

Describe the bug Unable to get a response from a container that uses System.Net.Sockets. I can connect and send a message from my debugging code but cannot get response. The socket container logs the connection, but nothing goes across the networkstream that we get from TcpClient.GetStream(). Does this tool support Sockets and NetworkStreams?

rakeshvanga commented 2 years ago

@SteveCurran Yes, the tool supports System.Net.Sockets and NetworkStreams. Can you share the logs from your dev machine? Also, can you share more information?

SteveCurran commented 2 years ago

@rakeshvanga thanks for the reply. Everything with the bridge works. I can connect to the socketservice and I can see in the logs of the socketservice running in AKS that the connection is made. However, when trying to read the response I get an invalid response error on the networkstream when trying to do networkstream.Read stating the connection has been closed. This seems to correspond with line 213 in the logs. I have attached the logs.

I am using VSCode on Windows 10.

Error is: An exception of type 'System.IO.IOException' occurred in System.Net.Sockets.dll but was not handled in user code: 'Unable to read data from the transport connection: An established connection was aborted by the software in your host machine..'

`internal static void MakeTcpRequest() { var requestHost = "socketservice.webservice.svc.cluster.local"; var requestPort = int.Parse(Environment.GetEnvironmentVariable("SOCKETSERVICE_SERVICE_PORT")); Console.WriteLine("request host: " + requestHost); Console.WriteLine("request port: " + requestPort);

using (TcpClient client = new TcpClient())
{

    if(client.ConnectAsync(requestHost, requestPort).Wait(5000))
    {
        using (NetworkStream socketStream = client.GetStream())
        {
            Utils.SendMessageToStream("hello socket", socketStream);
            Console.WriteLine("Sent request to socket...");

            string response = null;

            while (response == null)
            {
                string statusString = Utils.GetDataFrame(socketStream);
                Console.WriteLine("socket status: " + statusString);
                Console.WriteLine("socket response: " + serverResponse);
                response = "done";   
            }

            Console.WriteLine("response is no longer null...");
        }
    }
    else
    {
        Console.WriteLine("Failed to connect to socket. Connection timed out.");
    }                
}

}

internal static string GetDataFrame(NetworkStream ns) { var frameLengthBuffer = new byte[4]; ns.Read(frameLengthBuffer, 0, 4);

int dataLength = BitConverter.ToInt32(frameLengthBuffer, 0);

var data = new byte[dataLength];

int readBytes = 0;
int bufferSize = 1024;

while (readBytes < dataLength)
{
    readBytes += ns.Read(data, readBytes, Math.Min(bufferSize, dataLength - readBytes));
}

return Encoding.ASCII.GetString(data);

} bridge-library-2021-09-27-17-18-11-11032.txt `

SteveCurran commented 2 years ago

@rakeshvanga any word on this?

SteveCurran commented 2 years ago

This tool does not support System.Net.Sockets NetworkStreams.

rakeshvanga commented 2 years ago

@SteveCurran Apologies for delayed response. Due to my vacation and other work prioritization I couldn't get to investigate this issue earlier.

Thanks for sharing the code samples and log file.

If you see from the logs:

ServicePortForward: stream 48 connected.
2021-09-27T17:19:16.7616793Z | Library | TRACE | ServicePortForward: sending 42 bytes via stream 48
2021-09-27T17:19:16.8252705Z | Library | TRACE | ServicePortForward: received 163 bytes in stream 48.
2021-09-27T17:19:16.8420772Z | Library | TRACE | ServicePortForward: stream 48: StopLocal
2021-09-27T17:19:26.0140405Z | Library | TRACE | Accept 9070
2021-09-27T17:19:26.0470473Z | Library | TRACE | ServicePortForward: stream 56 connected.
2021-09-27T17:19:26.0476884Z | Library | TRACE | ServicePortForward: received 45 bytes in stream 56.
2021-09-27T17:19:26.0480640Z | Library | TRACE | ServicePortForward: stream 56 closed.

Bridge is able to communicate with its in-cluster service that helps in debugging. I looked into code and turns out we fixed this exact issue but seems like it is repro'ing again. I've re-opened the issue on our side. Regarding the fix and releasing this issue, it might not happen in next sprint and I would update once this is fixed.

SteveCurran commented 2 years ago

@rakeshvanga I was able to trap the specific line of code that creates the error when I send data across the socket, the data is received by the listener on port 9070 but the socket is immediately closed and it looks like it is related to the connection refused error below. This is from the pod logs.

Logging handled exception: System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: {"Message":"Connection refused 10.103.64.155:9070","SocketErrorCode":10061,"ErrorCode":111,"NativeErrorCode":111,"StackTrace":" at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)\n at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)\n at System.Net.Sockets.Socket.Connect(IPAddress address, Int32 port)\n at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)\n--- End of stack trace from previous location where exception was thrown ---\n at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)\n at System.Net.Sockets.TcpClient..ctor(String hostname, Int32 port)\n at Microsoft.BridgeToKubernetes.DevHostAgent.PortForward.ServicePortForwardConnector.ConnectAsync(Func2 connectHandler, Func4 receiveHandler, Func`2 closeHandler) in /src/devhostagent/PortForward/ServicePortForwardConnector.cs:line 66","Data":{},"InnerException":null,"HelpLink":null,"Source":"System.Net.Sockets","HResult":-2147467259}

SteveCurran commented 2 years ago

Closing this issue. B2K does work with networkstreams and sockets. It apparently was a problem with the way the code was reading the incoming response.