我创建了一个简单的网络游戏,它使用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的新实例,为什么这不起作用?服务器是否应该自动响应发送给它的每条消息?
答案 0 :(得分:2)
你正在做两个错误:首先是你一直在创建和重新创建连接。而是创建一次监听器,进入循环并阅读消息。在TCP广告中设置新连接会产生很多开销,特别是如果您只是发送小邮件。客户端也一样,连接一次,然后在需要时发送。
第二个问题是TCP是流式协议,并且没有消息边界。这意味着当您从TCP连接中读取时,您无法预先知道要读取多少数据,您需要提供一种自己分隔消息的方法:您可以添加消息边界,您可以在每个消息前加上一个标题包含邮件大小,您已经拥有相同的固定大小的所有邮件。无论哪种方式,您可能需要多次阅读才能获得完整的消息,或者一次阅读可能会为您提供多条消息。
关于第二个问题,你当然不能尝试阅读超过收到的内容,这可能是错误信息告诉你的内容。