TCPClient未关闭,而是等待客户端关闭它

时间:2016-11-02 20:21:17

标签: c# server tcpclient

我对编写TcpListener的问题很少。

第一个问题:

使用浏览器连接客户端后,我会看到请求。一切都好。但后来我面临着写作的问题。和客户收到该数据。它基本上永远不会得到服务器的回复。我需要那个冲洗功能吗?它是如何工作的 ?还有其他方法吗?

Porblem 2号更奇怪。当我调用client.close()时客户端不会去任何地方。它还在那里。浏览器仍然在寻找数据。当我在浏览器中终止连接时,只有Tcp客户端关闭并且循环再次启动。

namespace TestServer
{
    class Program
    {
       public static void Main()
        {
            TcpListener server;
            IPAddress addr = IPAddress.Parse("127.0.0.1");
            server = new TcpListener(addr, 80);


            server.Start();

            byte[] buffer = new byte[1024];


            while(true)
            {
                string data = null;
                Console.WriteLine("Awaiting for connections");
                TcpClient client = server.AcceptTcpClient();

                Console.WriteLine("Connected...");

                NetworkStream str = client.GetStream();

                int msgCounter;

                while ((msgCounter = str.Read(buffer, 0, buffer.Length)) != 0)
                {
                    Console.WriteLine("Processing stream...");

                    data += System.Text.Encoding.ASCII.GetString(buffer, 0, msgCounter);
                    Console.WriteLine("Reciaved: {0}", System.Text.Encoding.ASCII.GetString(buffer, 0, msgCounter));
                }


                byte[] response = System.Text.Encoding.ASCII.GetBytes("200 OK");
                str.Write(response, 0, response.Length);

                str.Flush();

                client.Close();

                buffer = new byte[1024];
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

TCP作为双向传输层协议并不表示“客户端已完成发送请求”信号的任何概念。

对开发人员来说意味着必须在应用程序(或任何其他更高级别)协议层中定义此类信令。

在您的情况下,它由HTTP本身在https://tools.ietf.org/html//rfc2616#section-5

中声明

因此,如果您打算实现HTTP服务器,则必须解析具有确定请求结束的确定方式的HTTP请求(请参阅上面的链接)。

总结一下:你需要知道你已经完全阅读了这个请求,你可能会开始处理它并生成/发送响应。

答案 1 :(得分:0)

我建议您从a million times proven working MSDN example of TcpListener class开始。另外,我可以指出明确的错误方法:

  1. 不要重新创建缓冲区,这是浪费资源。
  2. 如果使用TCP套接字,请不要将浏览器用作测试客户端。任何浏览器都试图以某种方式纠正HTTP协议错误,并且可以以非常不可预测的方式执行此操作。如果您需要HTTP级别的调试,请使用Fiddler,用于较低级别 - Microsoft网络监视器,Netcat的Wireshark。
  3. 阅读一些关于TCP / IP网络的书可能很有用。特别是,你会知道,没有"关闭"通过协议定义进行TCP连接的操作或命令,TcpClient只是模拟它。相反,对等方可以发送" shutdown"另一个,它确实意味着它不再计划发送数据,但可以读取它。只有在两个对等方发送了" shutdown"之后才能认为连接已关闭。并收到"关机"来自彼此。