【发布时间】:2017-04-06 04:35:04
【问题描述】:
通常我能够自己解决问题,但我不得不再次寻求帮助。如果有些内容不连贯,我提前道歉,因为我似乎有点发烧。
我目前正在 XNA 中制作非常简单的游戏。这是一款 2D 高空射击游戏。唯一的动作是玩家射击子弹。问题是,我想让它成为多人游戏(同一网络中的玩家)。
我考虑过以下方法:
-
其中一个玩家托管服务器
- 服务器保存每个玩家和子弹的位置信息
-
服务器创建新世界(由玩家和子弹组成)并在新线程中更新它,如下所示:
while (true) { lock (world) world.update(); Thread.Sleep(worldUpdatePeriod); } 服务器为每个需要处理的玩家创建新线程
-
玩家连接到服务器
-
他们应该定期从服务器接收信息他们应该画什么:
class Asset { string type; Vector2 position; } 他们应该能够从键盘和鼠标发送输入来移动和射击。
-
现在,重点。播放器可以向服务器发送三种类型的消息:
- “可以阅读”
- “鼠标”
-
“键盘”
string header = "CAN READ"; lock (streamWriter) { streamWriter.WriteLine(header); }
服务器,在一个单独的线程中为每个客户端等待消息
streamReader = new StreamReader(networkStream);
streamWriter = new StreamWriter(networkStream);
streamWriter.AutoFlush = true;
while (true)
{
if (networkStream.DataAvailable)
{
string header;
lock (streamReader)
{
header = Convert.ToString(streamReader.ReadLine());
Console.WriteLine($"Header received: {header}");
handleHeader(header);
}
}
}
现在如果标题是,例如,“CAN READ”
-
服务器
case "CAN READ": if (streamWriter.BaseStream.CanRead) { lock (streamWriter) { streamWriter.WriteLine(server.world.assets.Count); foreach (var asset in server.world.assets) { streamWriter.WriteLine(asset.type); streamWriter.WriteLine(asset.position.X); streamWriter.WriteLine(asset.position.Y); } } } break; -
客户
int assetCount = Convert.ToInt32(streamReader.ReadLine()); List<Asset> receivedAssets = new List<Asset>(); lock (streamReader) { for (int i = 0; i < assetCount; i++) { string type = Convert.ToString(streamReader.ReadLine()); int x = Convert.ToInt32(streamReader.ReadLine()); int y = Convert.ToInt32(streamReader.ReadLine()); receivedAssets.Add(new Asset(type, new Vector2(x, y))); } return receivedAssets; }
当然,Client 类和 handleClient 类有单独的 streamReaders 和 streamWriters。
你明白了。我正在尝试将来自服务器的每个 WriteLine() 与来自客户端的 ReadLine() 等进行匹配。它工作正常!直到我将用户输入添加到混合物中。
一旦我发送键盘输入(如上所示匹配),它似乎可以工作,偶尔会出现 System.FormatException,这意味着某些 ReadLine() 读取错误的 WriteLine()。我能够抓住并重试。
一旦我发送鼠标输入,一切都会变得糟糕。不匹配的异常变得更频繁,以至于“游戏”无法进行。所以我想知道我的方法是否有问题。对于问题的长度,我深表歉意,我试图简洁,但也觉得需要提供上下文。谢谢,如果你坚持到最后,我很乐意回答任何进一步的问题,因为我在过去几天试图解决它。
【问题讨论】:
-
TCP 连接? TCP 是一种流协议,没有消息边界的概念。请参阅stackoverflow.com/questions/17446491/tcp-stream-vs-udp-message 了解一个类似的问题。
标签: c# multithreading xna tcpclient streamreader