C# and TCP/IP, opinions on microsoft's implementation
Ok, a third question in my C# - TCP/IP series.

When a TCP/IP connection is initiated there is a handshake sequence.
When a TCP/IP connection is terminated there is a handshake sequence.

In the sample C# code, I'm testing how Microsoft's TcpClient/Socket code behaves during the termination sequence.  I'm using Tcpview.exe, a WinXP application to monitor the connection states (Established, Close_wait, Fin_wait2, etc).

I do two separate tests.  One that involves a "Write(a)" method call and a separate test which has that method call commented out.  When "Write(a)" is called "ReadString()" in the IOException block is not called (because it's commented out) and vice versa.

I'm observing the socket behavior (as reported by Tcpview.exe) AFTER server.Close() call.

In the 'no write' case, the string "Went Through?" is printed on the client and the server socket has Fin_wait2 state, while the client socket has Close_wait state.

In the 'write' case, the string "Went Through?" is NOT printed and both the client socket and the server socket are outright closed immediately following the failed "Write(a)", going from Established to gone from listing, no intermediate steps are shown.

And the question is, is the Write call properly implemented by Microsoft (I'm using .NET 3.5)?  Is this behavior the correct one?  I feel that the socket state should be the same following a Write call as it is when only Reads are done.  Meaning that both sockets should have Fin_wait2 and Close_wait as was the case for a Read and the client's non-Closed TcpClient object should allow a "ReadString()" to succeed giving me the "Went Through?" string instead of discarding it and throwing an IOException.

My test program is as follows:

        static void fClient()
        {
            TcpClient client = new TcpClient("localhost", 22320);
            int iterations = 0;

            BinaryReader br = new BinaryReader(client.GetStream());
            BinaryWriter bw = new BinaryWriter(client.GetStream());
            while (true)
            {
                try
                {

                    Thread.Sleep(1000);
                    bw.Write("a"); //test 'write'
                    iterations++;
                    if (iterations > 22)
                        throw new IOException();
                }
                catch (IOException ioe)
                {
                    Console.WriteLine("EXCEPTION");
                    Console.WriteLine(br.ReadString()); //test 'no write'
                    Thread.Sleep(10000);
                    client.Close();
                    Thread.Sleep(10000);
                    break;
                }
            }
        }

        static void Main(string[] args)
        {
            TcpListener server = new TcpListener(22320);
            server.Start();

            new Thread(fClient).Start();

            TcpClient client = server.AcceptTcpClient();

            BinaryWriter binWrite = new BinaryWriter(client.GetStream());
            binWrite.Write("Went Through?");
            binWrite.Flush();

            Thread.Sleep(20000);
            client.Close();
            Thread.Sleep(20000);
        }
C# and TCP/IP, opinions on microsoft's implementation
===

Ok, a third question in my C# - TCP/IP series.

When a TCP/IP connection is initiated there is a handshake sequence.
When a TCP/IP connection is terminated there is a handshake sequence.

In the sample C# code, I'm testing how Microsoft's TcpClient/Socket code behaves during the termination sequence.  I'm using Tcpview.exe, a WinXP application to monitor the connection states (Established, Close_wait, Fin_wait2, etc).

I do two separate tests.  One that involves a "Write(a)" method call and a separate test which has that method call commented out.  When "Write(a)" is called "ReadString()" in the IOException block is not called (because it's commented out) and vice versa.

I'm observing the socket behavior (as reported by Tcpview.exe) AFTER server.Close() call.

In the 'no write' case, the string "Went Through?" is printed on the client and the server socket has Fin_wait2 state, while the client socket has Close_wait state.

In the 'write' case, the string "Went Through?" is NOT printed and both the client socket and the server socket are outright closed immediately following the failed "Write(a)", going from Established to gone from listing, no intermediate steps are shown.

And the question is, is the Write call properly implemented by Microsoft (I'm using .NET 3.5)?  Is this behavior the correct one?  I feel that the socket state should be the same following a Write call as it is when only Reads are done.  Meaning that both sockets should have Fin_wait2 and Close_wait as was the case for a Read and the client's non-Closed TcpClient object should allow a "ReadString()" to succeed giving me the "Went Through?" string instead of discarding it and throwing an IOException.

My test program is as follows:

        static void fClient()
        {
            TcpClient client = new TcpClient("localhost", 22320);
            int iterations = 0;

            BinaryReader br = new BinaryReader(client.GetStream());
            BinaryWriter bw = new BinaryWriter(client.GetStream());
            while (true)
            {
                try
                {

                    Thread.Sleep(1000);
                    bw.Write("a"); //test 'write'
                    iterations++;
                    if (iterations > 22)
                        throw new IOException();
                }
                catch (IOException ioe)
                {
                    Console.WriteLine("EXCEPTION");
                    Console.WriteLine(br.ReadString()); //test 'no write'
                    Thread.Sleep(10000);
                    client.Close();
                    Thread.Sleep(10000);
                    break;
                }
            }
        }

        static void Main(string[] args)
        {
            TcpListener server = new TcpListener(22320);
            server.Start();

            new Thread(fClient).Start();

            TcpClient client = server.AcceptTcpClient();

            BinaryWriter binWrite = new BinaryWriter(client.GetStream());
            binWrite.Write("Went Through?");
            binWrite.Flush();

            Thread.Sleep(20000);
            client.Close();
            Thread.Sleep(20000);
        }