KMC
KMC

Reputation: 20036

Endless loop responds from server

I have the following piece of code to listen to a port which is 55000.

static void TcpEchoServer(string _servPort)
{
    int servPort = Convert.ToInt32(_servPort);

    TcpListener listener = null;

    try
    {
        listener = new TcpListener(IPAddress.Any, servPort);
        listener.Start();
    }
    catch (SocketException sec)
    {
        Console.WriteLine(sec.ErrorCode + ": " + sec.Message);
        Environment.Exit(sec.ErrorCode);
    }

    byte[] rcvBuffer = new byte[BUFSIZE];
    int bytesRcvd;

    for (; ; )
    {
        TcpClient client = null;
        NetworkStream netStream = null;

        try
        {
            // Get client connection and stream
            client = listener.AcceptTcpClient();
            netStream = client.GetStream();
            Console.Write("Handling client - ");

            // Receive until client closes connection, indicated by 0 return value
            int totalBytesEchoed = 0;
            bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length);

            while (bytesRcvd > 0)
            {
                netStream.Write(rcvBuffer, 0, bytesRcvd);
                totalBytesEchoed += bytesRcvd;
            }

            Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);

            // Close stream and socket
            netStream.Close();
            client.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            netStream.Close();
        }
    }
}

Once I open started the server, I telnet on my command prompt and send a message, but kept getting a loop responds on my client but no responds on my server. Anyone spot I problem? I can't. I develop on Window 7 VS2010 C# on VMWare on my Mac machine where I telent from my Mac terminal.

screenshot1

[EDIT - code answer]

I simply assign the bytes received variable within the while loop, so it won't loop as soon as it completes. Thank you for pointing the problem out. Following is my solution code:

while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
{
    netStream.Write(rcvBuffer, 0, bytesRcvd);
    totalBytesEchoed += bytesRcvd;
}

Upvotes: 2

Views: 984

Answers (1)

M.Babcock
M.Babcock

Reputation: 18965

The culprit is:

 while (bytesRcvd > 0)

As long as any message was received it will loop indefinitely (you don't have a condition to prevent this).

This could probably be replaced with a simple if unless for some reason (not obvious in your code) you need it to loop:

if (bytesRcvd > 0)

On second look, it almost looks like you're trying to verify that all of the bytes are transmitted by using this code:

while (bytesRcvd > 0)
{
    netStream.Write(rcvBuffer, 0, bytesRcvd);
    totalBytesEchoed += bytesRcvd;
}

The third parameter isn't a byref argument, so it won't be updated with the value that was actually sent (if less than the value passed in). Write differs slightly from Read in that it will actually throw a SocketException if it was unable to transfer the number of bytes requested (as opposed to informing you of how many were successful). I would probably change it to:

if (bytesRcvd == 0)
    throw new SocketException(String.Format("Unable to receive message");

netStream.Write(rcvBuffer, 0, bytesRcvd);
totalBytesEchoed += bytesRcvd;

Or better yet implement some fundamental message framing to allow your application to know how many bytes it should expect.

Upvotes: 3

Related Questions