Search code examples
c#tcpclient

C# tcpclient not writing to socket...or maybe I'm not reading all of the response?


I'm trying to write a C# console app to interface with a PC Miler telnet server. I managed to get this to work in powershell, but my C# code is not working.

static void Main(string[] args)
{
    byte[] ReadBuffer = new byte[1024];
    string[] stringSeparators = new string[]{"READY"};

    try
    {
        TcpClient Socket = new TcpClient("myServer", 8320);

        if (Socket.Connected) {
            NetworkStream netStream = Socket.GetStream();
            string PCMSResponse = "";

            // Check for the READY prompt
            if (netStream.CanRead) {
                int byteRead = 0;
                while (netStream.DataAvailable) {
                    byteRead = netStream.Read(ReadBuffer, 0, ReadBuffer.Length);
                    PCMSResponse += Encoding.ASCII.GetString(ReadBuffer, 0 , byteRead).Trim();
                }
            } else {
                Console.WriteLine("Cannot read from myServer");
            }
            Thread.Sleep(1000);

            // Get New Trip
            if (netStream.CanWrite) {
                Byte[] PCMSCommandBuffer = Encoding.ASCII.GetBytes("PCMSNewTrip");
                netStream.Write(PCMSCommandBuffer, 0 , PCMSCommandBuffer.Length);
                Thread.Sleep(1000);
            } else {
                Console.WriteLine("Cannot write to myServer.");
            }
            if (netStream.CanRead) {
                int byteRead = 0;
                while (netStream.DataAvailable) {
                    byteRead = netStream.Read(ReadBuffer, 0, ReadBuffer.Length);
                    PCMSResponse += Encoding.ASCII.GetString(ReadBuffer, 0, byteRead).Trim();
                }
            } else {
                Console.WriteLine("Cannot read from myServer");
            }
            string[] ResponseArray = PCMSResponse.Split(stringSeparators, StringSplitOptions.None);
            int c = ResponseArray.Length - 2;
            string TripID = ResponseArray[c].Replace(System.Environment.NewLine, "").Replace("\0", "");
            Console.WriteLine(PCMSResponse);
        }
    }
    catch (SocketException)
    {
        Console.WriteLine("Unable to connect to server")
    }
}

Expected output

ALK PCMILER SERVER READY
pcmsnewtrip
53
READY

Actual output

ALK PCMILER SERVER READY

It seems like I am not actually writing to the server because if I were to write an invalid command to the server I would see an error like this:

ALK PCMILER SERVER READY
pmctripnew
NO SUCH FUNCTION
READY

I know I can write to the socket because I'm not getting my error message Cannot write to myServer.

Not sure what I'm doing wrong. :(

Let me know if you'd also like to see the powershell code.

EDIT - If you're going to edit this post, at least keep the expected output AS EXPECTED! Changing the expected output changes the intent of the post. (EG, if I want apples but you edit my post to ask for oranges, I'm not going to get the correct answer.)


Solution

  • So the issue turns out to be that the NetworkStream.Write method does not end a string with a line terminator. As a result, when I wrote my PCMSCommandBuffer bytes to the stream, the command was never processed by the server (because its waiting for more of the command or the enter key to let it know you're done). My solution was to assign the stream to a StreamWriter. Then I can use the WriteLine method whichdoes send a line terminator.

    streamWriter = new StreamWriter(netStream);
    // Get New Trip
    if (netStream.CanWrite) {
        Byte[] PCMSCommandBuffer = Encoding.ASCII.GetBytes("PCMSNewTrip");
        //netStream.Write(PCMSCommandBuffer, 0 , PCMSCommandBuffer.Length);
        streamWriter.WriteLine("PCMSNewTrip");
        //netStream.Flush();
        streamWriter.Flush();
        Console.WriteLine(PCMSCommandBuffer.Length + " PCMSNewTrip");
        Thread.Sleep(1000);
    } else {
        Console.WriteLine("Cannot write to EW-APP1.");
    }