回复时出现 TCP 错误

TCP error on reply

我创建了一个简单的网络游戏,它使用 TCP 套接字来获取其他玩家的数据。我有两个不同的 类,一个服务器和一个客户端。当我一次只发送一条消息时,一切都很好:

客户:

public void ClientTester()
{
    thread = new Thread(SendPosition);
    thread.Start();
}

private void SendPosition()
{
    while (true)
    {
        using (TcpClient client = new TcpClient())
        {
            client.Connect("127.0.0.1", 82);
            using (NetworkStream n = client.GetStream())
            {
                BinaryWriter w = new BinaryWriter(n);
                w.Write("Position:" + GameFiles.Player.Player.position.ToString());
                w.Flush();
                string msg = new BinaryReader(n).ReadString();
                parseString(msg, "Position:", 9);
            }
        }

        Thread.Sleep(60);
    }
}

服务器:

public void ServerTester()
{
    thread = new Thread(TheadedMethod);
    thread.Start();
}

private void TheadedMethod()
{
    while (true)
    {
        TcpListener listener = new TcpListener(IPAddress.Any, 82);
        listener.Start();
        using (TcpClient c = listener.AcceptTcpClient())
        using (NetworkStream n = c.GetStream())
        {
            parseString(msg, "Position:", 9);
            BinaryWriter w = new BinaryWriter(n);
            w.Write("Position:" + GameFiles.Player.Player.position.ToString());
            w.Flush();
        }
        listener.Stop();
    }
}

这是新代码:

客户:

public void ClientTester()
{
    thread = new Thread(SendPosition);
    thread.Start();

    SendMousePosition();
}

private void SendPosition()
{
    while (true)
    {
        using (TcpClient client = new TcpClient())
        {
            client.Connect("127.0.0.1", 82);
            using (NetworkStream n = client.GetStream())
            {
                BinaryWriter w = new BinaryWriter(n);
                w.Write("Position:" + GameFiles.Player.Player.position.ToString());
                w.Flush();
                string msg = new BinaryReader(n).ReadString();
                parseString(msg, "Position:", 9);
            }
        }

        Thread.Sleep(60);
    }
}

private void SendMousePosition()
{
    using (TcpClient client = new TcpClient())
    {
        client.Connect("127.0.0.1", 82);
        using (NetworkStream n = client.GetStream())
        {
            BinaryWriter w = new BinaryWriter(n);
            w.Write("MousePosition:" + cursor.mousePosition());
            w.Flush();
            string msg = new BinaryReader(n).ReadString();
            parseString(msg, "MousePosition:", 14);
        }
    }
}

服务器:

public void ServerTester()
{
    thread = new Thread(TheadedMethod);
    thread.Start();
}

private void TheadedMethod()
{
    while (true)
    {
        TcpListener listener = new TcpListener(IPAddress.Any, 82);
        listener.Start();
        using (TcpClient c = listener.AcceptTcpClient())
        using (NetworkStream n = c.GetStream())
        {
            string msg = new BinaryReader(n).ReadString();
            if (msg == "Position:")
            {
                parseString(msg, "Position:", 9);
                BinaryWriter w = new BinaryWriter(n);
                w.Write("Position:" + GameFiles.Player.Player.position.ToString());
                w.Flush();
            }
            if (msg == "MousePosition:")
            {
                parseString(msg, "MousePosition:", 14);
                BinaryWriter w = new BinaryWriter(n);
                w.Write("MousePosition:" + cursor.mousePosition());
                w.Flush();
            }
        }
        listener.Stop();
    }
}

当我尝试发送两条消息时收到错误消息:

Unable to read beyond the end of the stream.

在客户端方法 SendPosition() 的这一行中:

string msg = new BinaryReader(n).ReadString();

为什么即使我创建了一个新的 BinaryReader 实例,它仍然不起作用?服务器不应该自动响应发送给它的每条消息吗?

你做错了两件事:第一个是你一直在创建和重新创建连接。而是创建一次监听器,进入循环并读取消息。在 TCP 中建立一个新连接会增加很多开销,尤其是当您只是发送小消息时。客户端也是一样,连接一次,需要的时候发送。

第二个问题是TCP是一个streaming协议,没有消息边界。这意味着当您从 TCP 连接读取时,您无法事先知道您将读取多少数据,您需要提供一种自己分隔消息的方法:您可以添加消息边界,您可以在每条消息前加上一个包含消息大小,您的所有消息都是相同的固定大小。无论哪种方式,您可能需要阅读多次才能获得完整的信息,或者一次阅读可能会给您多条信息。

关于第二个问题,您当然不能尝试阅读超过已收到的内容,这可能是错误消息告诉您的内容。