如何将TCP流中的特定字符串格式反序列化为Player对象
将TCP流中的消息反序列化为Player对象
问题描述
我从TCP流中收到以下格式的消息:
["bilbo,1,0,0,0,0,1,2022-11-21 19:06:10","mangnoune,1,0,0,0,0,2,2022-11-21 19:08:18"] ["string, int, int, float, float, float, int, DateTime","next array pattern"]
需要把其中的玩家数据反序列化为如下定义的Player类对象(示例包含2个玩家):
class Player { string Name; int Level; int Xp; float X; float Y; float Z; int Status; DateTime LastPlayed; }
实现步骤与代码示例
1. 解析TCP消息为字符串数组
首先将TCP流中读取到的JSON格式字符串解析为字符串数组,其中第一个数组的每个元素对应一个玩家的逗号分隔数据,第二个数组为格式说明,可忽略。
2. 拆分字段并转换类型
对每个玩家数据字符串按逗号拆分,将各字段转换为Player类对应的类型,最终实例化对象。
以下是C#的完整实现代码:
using System; using System.Collections.Generic; using System.Text.Json; // 优化Player类定义,改为公共属性方便操作 public class Player { public string Name { get; set; } public int Level { get; set; } public int Xp { get; set; } public float X { get; set; } public float Y { get; set; } public float Z { get; set; } public int Status { get; set; } public DateTime LastPlayed { get; set; } } public class PlayerDeserializer { public static List<Player> DeserializeFromTcpMessage(string tcpMessage) { var playerDataArray = JsonSerializer.Deserialize<string[]>(tcpMessage); var players = new List<Player>(); foreach (var dataStr in playerDataArray) { var fields = dataStr.Split(','); // 先验证字段数量是否符合要求 if (fields.Length != 8) continue; // 使用安全转换避免格式异常导致崩溃 if (int.TryParse(fields[1], out int level) && int.TryParse(fields[2], out int xp) && float.TryParse(fields[3], out float x) && float.TryParse(fields[4], out float y) && float.TryParse(fields[5], out float z) && int.TryParse(fields[6], out int status) && DateTime.TryParse(fields[7], out DateTime lastPlayed)) { players.Add(new Player { Name = fields[0], Level = level, Xp = xp, X = x, Y = y, Z = z, Status = status, LastPlayed = lastPlayed }); } } return players; } } // 调用示例 class Program { static void Main() { string tcpReceivedData = "[\"bilbo,1,0,0,0,0,1,2022-11-21 19:06:10\",\"mangnoune,1,0,0,0,0,2,2022-11-21 19:08:18\"]"; var playerList = PlayerDeserializer.DeserializeFromTcpMessage(tcpReceivedData); foreach (var player in playerList) { Console.WriteLine($"玩家名称:{player.Name},等级:{player.Level},最后游玩时间:{player.LastPlayed}"); } } }
关键注意点
- 错误处理:用
TryParse系列方法替代直接Parse,避免因TCP消息格式异常导致程序崩溃。 - 格式筛选:如果TCP流中会混入格式说明数组(如示例中的第二个数组),需要额外判断数组元素是否为玩家数据(比如检查字段数量是否为8)。
- 类定义优化:原
Player类的私有字段改为公共属性,方便后续访问和扩展。
内容的提问来源于stack exchange,提问作者user17020926
相关产品推荐
相关产品推荐

