chronoxor / NetCoreServer

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution
https://chronoxor.github.io/NetCoreServer
MIT License
2.77k stars 577 forks source link

Very Simple TcpClient - Connects but doesn't receive data. #206

Open jtolar opened 2 years ago

jtolar commented 2 years ago

I am working on writing a Rlogin proxy app using NetCoreServer. The app consist of a Rlogin Server, a Ssh Tunnel Client and a Rlogin client. The Rlogin server accepts a connection, authenticates and returns some data to the screen. If the authentication detects a "magic string" it will create a Ssh client with a port forward and then create a Rlogin Client that connects through the tunnel to proxy data between the server session and the tunneled connection. The Rlogin server works just fine as does the Ssh tunnel client (Renci Ssh.Net) but the Rlogin Client will connect and send data but will not receive any data back. I simplified the scenario and just used the Rlogin client to connect to a reliable working rlogin server minus the tunnel code. I can see the data coming in to the server but still not getting data back even though I know data is being sent from the server. I then simplified the code even more and did the most basic of TcpClient and still nothing. Am I missing something???

The Rlogin protocol exchange goes like this...

As I said in an attempt to create the most simple client I tried the following code and it will connect but not receive any data back from the server even though I see it coming back from the other programs.


public class RloginClient2 : TcpClient
    {
        public RloginClient2(IPAddress address, int port) : base(address, port)
        {

        }

        protected override void OnConnected()
        {
            ConsoleWrite.RloginClientMessage("Sending Login String");
            SendAsync("\0sysop\0sysop\0ansi\0");
        }

        protected override void OnReceived(byte[] buffer, long offset, long size)
        {
            ConsoleWrite.RloginClientMessage($"Received [{size}] {Encoding.UTF8.GetString(buffer)}");
        }

        protected override void OnError(System.Net.Sockets.SocketError error)
        {
            Console.WriteLine($"[Error] {Enum.GetName(typeof(System.Net.Sockets.SocketError), error)}");
            base.OnError(error);
        }
    }

To use the client I use

var client = new RloginClient2(IPAddress.Parse("192.168.7.3").MapToIPv4(), 516); client.Connect();

Here is the log from the server side....

Rlogin session 8a933e65-659e-438a-b06d-3eaebfa7962c connected! [RloginServer Received] user serveruser ansi Sending ACK Sending Ansi file Sending Echo Server Message Sending Echo Reply: user serveruser ansi

When using a client like SyncTERM I get all the data back on the screen that is sent from the server.

chronoxor commented 2 years ago

Please try client.ConnectAsync(); to connect asynchronously with start receiving data. If you call client.Connect(); you'll connect synchronously and you should start receiving data manually by calling Receive() or ReceiveAsync() in your OnConnected() handler.

jtolar commented 2 years ago

That worked... thank you.