关键在于将含字符串的完整数据结构整体序列化为字节流并确保两端一致还原,推荐优先使用JSON,因其语言无关、可读性强、自动处理UTF-8编码;需防范TCP粘包/断包及编码不一致问题。

字符串变量本身不是结构化对象,但常作为结构化数据的载体。要实现其状态在网络间可靠传输,关键不在“序列化字符串”,而在于把含字符串的完整数据结构(比如用户信息、配置项、消息体)转成字节流,并确保收发两端能一致还原。
明确你要传的是什么数据
单个纯字符串(如 "hello")直接 .getBytes() 或 .encode() 就能发,但实际场景中极少只传一个字符串。更多是带字段的组合数据,例如:
- 用户名 + 时间戳 + 操作类型(如登录日志)
-
API 请求参数(如
{"query": "java", "page": 2}) - 带元信息的消息体(如 sender="Alice", content="Hi", ts=1715480123)
这些必须整体序列化,否则接收方无法区分哪段是名字、哪段是内容。
选对序列化方式:JSON 最常用也最稳妥
对含字符串的结构化数据,推荐优先用 JSON 格式,原因很实在:
- 语言无关:Java/Python/JS/PHP 都原生支持,服务端和客户端不用同语言也能互通
- 可读可调试:传输内容是明文字符串,抓包或日志里一眼能看懂
- 自动处理字符串编码:中文、emoji、特殊符号不会乱码(前提是统一 UTF-8)
示例(Python 发送):
import json, socket<br>data = {"user": "张三", "action": "submit", "token": "abc123"}<br>payload = json.dumps(data, ensure_ascii=False).encode('utf-8')<br># 发送到服务端<br>sock.send(payload)对应 Java 接收端只需:
InputStream is = socket.getInputStream();<br>String jsonStr = new String(is.readAllBytes(), StandardCharsets.UTF_8);<br>JsonObject obj = JsonParser.parseString(jsonStr).getAsJsonObject();<br>String user = obj.get("user").getAsString(); // → "张三"注意网络传输的两个隐形坑
即使序列化正确,裸发字节流仍可能出错:
-
粘包/断包问题:TCP 是字节流,连续发两次
"a"和"b",对方可能一次收到"ab",也可能分两次收到"a"和"b"。解决办法是在数据前加长度头(如 4 字节 int 表示后续 JSON 字节数),或用换行符分隔 - 编码不一致:发送端用 UTF-8,接收端按 ISO-8859-1 解,中文全变问号。务必显式指定编码,不要依赖平台默认
什么时候考虑二进制序列化?
如果对性能和体积敏感(如高频物联网上报、游戏实时同步),且收发双方都是 Java,可考虑 ObjectOutputStream 或 Kryo;Python 可用 pickle。但要注意:
-
pickle和 Java 原生序列化 不跨语言,Python 发的 pickle,Java 无法直接读 - 它们可能执行任意代码,**切勿反序列化不可信来源的数据**(严重安全风险)
- 版本兼容性差:类字段增删后,旧版程序可能解析失败
所以,除非内网可控、同技术栈、且有明确性能瓶颈,否则别轻易弃用 JSON。

















