我有一个运行良好的客户机/服务器应用程序,但它缺少一个关键的行为,使它更加可靠。
现在,就网络能力而言,它还远远没有“强大”。我正在努力做到这一点,研究让我相信我需要某种协议来确保在网络传输过程中不会丢失任何数据。
我听说过一些方法。我认为最适合我们的情况是使用终结者,类似于<EOF>标记。我的问题是我不确定最好的方法来实现这一点。
下面是一些代码片段,在找到最佳解决方案后,我将对其进行修改,以包含终止符。
客户:

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()不是流结尾的有效测试。这是对现有数据的测试。
所以你过早地终止了你的阅读循环,从而在接收器上丢失了数据,在发送器上得到了重置。
在接收到来自api的eos指示之前,您应该只阻塞read()方法,不管c中是什么。
您不需要自己的附加EOS指示器。

10-08 09:07
查看更多