C# 指示所有数据已通过网络接收的最佳方式?

C# 指示所有数据已通过网络接收的最佳方式?,c#,networking,tcp,tcpclient,tcplistener,C#,Networking,Tcp,Tcpclient,Tcplistener,我有一个运行良好的客户机/服务器应用程序,但它缺少一个关键的行为,使其更加可靠 目前,就网络能力而言,它还远远不够“强大”。我正试图实现这一目标,研究使我相信,我需要某种协议,以确保在网络传输过程中不会丢失任何数据 我听说过几种方法。我认为对我们的情况最有效的一种方法是使用终止符,类似于标记。我的问题是,我不确定实现这一点的最佳方式 这里有几个代码片段,在找到最佳解决方案后,我将对它们进行修改,以包含一个终止符 客户: TcpClient client = new TcpClient(); c

我有一个运行良好的客户机/服务器应用程序,但它缺少一个关键的行为,使其更加可靠

目前,就网络能力而言,它还远远不够“强大”。我正试图实现这一目标,研究使我相信,我需要某种协议,以确保在网络传输过程中不会丢失任何数据

我听说过几种方法。我认为对我们的情况最有效的一种方法是使用终止符,类似于
标记。我的问题是,我不确定实现这一点的最佳方式

这里有几个代码片段,在找到最佳解决方案后,我将对它们进行修改,以包含一个终止符

客户:

TcpClient client = new TcpClient();

client.Connect(hostname, portNo);

using (var stream = client.GetStream())
{
    //send request

    stream.Write(data, 0, data.Length);
    stream.Flush();

    //read server response

    if (stream.CanRead)
    {
        byte[] buffer = new byte[1024];
        string response = "";
        int bytesRead = 0;

        do
        {
            bytesRead = stream.Read(buffer, 0, buffer.Length);

            response += Encoding.ASCII.GetString(buffer, 0, bytesRead);

        } //trying to replace 'DataAvailable', it doesn't work well
        while (stream.DataAvailable); 
    }
}
注意,我试图替换检查流中更多数据的
stream.DataAvailable
方法。它一直在制造问题

服务器:

var listener = new TcpListener(IPAddress.Any, portNo);

listener.Start();

var client = listener.AcceptTcpClient();

using (var stream = client.GetStream())
{
    var ms = new System.IO.MemoryStream();

    byte[] buffer = new byte[4096];
    int bytesRead = 0;

    do
    {
        bytesRead = stream.Read(buffer, 0, buffer.Length);

        ms.Write(buffer, 0, bytesRead);

    } //also trying to replace this 'stream.DataAvailable'
    while (stream.DataAvailable);

    ms.Position = 0;

    string requestString = Encoding.UTF8.GetString(ms.ToArray());

    ms.Position = 0;

    /*
        process request and create 'response'
    */

    byte[] responseBytes = Encoding.UTF8.GetBytes(response);

    stream.Write(responseBytes, 0, responseBytes.Length);
    stream.Flush();
}

因此,给定这两个代码示例,我如何修改它们以包括并检查某种数据终止符,该终止符指示停止读取数据是安全的?

您可以依靠TCP在FIN之前传输所有数据。代码的问题是available()不是流结束的有效测试。这是对现有数据的测试

因此,您过早地终止了读取循环,从而在接收方丢失了数据,在发送方得到了重置

您应该只阻塞Read()方法,直到从API收到EOS指示,无论C#中是什么

您不需要自己额外的EOS指示器。

我们在项目的两端都使用了EOS(流结束)指示器。我不会发布完整的代码示例,但这里有一个关于其工作原理的小片段:

stream.Write(data, 0, data.Length);
stream.WriteByte(Convert.ToByte(ConsoleKey.Escape));
stream.Flush();

在该流的接收端,循环逐字节读取数据。一旦它接收到
ConsoleKey.Escape
字节,它就会终止循环。它起作用了

不使用http有什么具体原因吗?是的,但这有点无关紧要。我不想在这里讨论这个问题。所以我想你想要流媒体和开放式的连接?不一定。服务器应用程序是多线程的,总是在侦听,并在完成处理后关闭每个连接。我也不太清楚这是怎么回事,因为它与数据本身无关。TCP是否已经确保了“在连接到局域网、内部网或公共互联网的计算机上运行的程序之间可靠、有序、经错误检查的八位字节流的传递。”()。这是UDP协议吗?