IPAddress.HostToNetworkOrder参数含义及代码计算逻辑问询
解析CloseAndSend方法中长度计算的作用
咱们一步步拆解这个参数的作用,结合你提供的填充代码来看就清晰多了。
先看你填充BinaryWriter的代码:
byte EOL = 0; BinaryWriter writer = new BinaryWriter(new MemoryStream()); writer.Write(UTF8Encoding.UTF8.GetBytes("API")); writer.Write(EOL); writer.Write((int)0); writer.Write(UTF8Encoding.ASCII.GetBytes("v100..155"));
再对应CloseAndSend里的核心代码:
protected override void CloseAndSend(BinaryWriter request, uint lengthPos) { request.Seek((int)lengthPos, SeekOrigin.Begin); request.Write(IPAddress.HostToNetworkOrder((int)(request.BaseStream.Length - lengthPos - sizeof(int)))); //更多代码 }
接下来逐个解析公式里的每个部分:
request.BaseStream.Length:整个流的总字节数,你提到这里是17,咱们核对下:"API"占3字节 + EOL占1字节 + 占位int占4字节 + "v100..155"占9字节,3+1+4+9=17,完全对应。lengthPos:这个是你之前写入的占位(int)0的起始位置,也就是前面"API"+EOL的总长度(3+1=4),所以lengthPos的值是4。sizeof(int):就是那个占位int的字节数,C#里int默认占4字节。
代入公式计算:17 - 4 - 4 = 9,正好是你最后写入的"v100..155"的字节数。
这个计算的核心作用
它是在计算从lengthPos指向的占位字段之后,到流末尾的有效负载长度,这是很多网络协议的常见设计逻辑:
- 先写入固定格式的头部内容(这里是"API"+EOL)
- 预留一个int字段用来存储后续有效数据的长度(先写0占位)
- 写入实际的业务数据(也就是负载内容)
- 最后回到预留的长度字段位置,把占位的0替换成真实的负载长度,同时用
IPAddress.HostToNetworkOrder转换成网络字节序(大端序),保证不同字节序的系统都能正确解析这个长度值。
至于为什么要减去sizeof(int)?因为lengthPos指向的是要写入长度的那个字段本身的起始位置,这个字段自己占4字节,我们需要的是这个字段后面所有数据的长度,所以必须把字段本身的字节数减掉,得到的才是真正的负载长度。
内容的提问来源于stack exchange,提问作者w0051977
相关产品推荐
相关产品推荐

