把消息长度写到消息包中

今天在 SOCKET编程时,遇到一个问题。通常 SOCKET的消息包中,需要包含一个长度字段,这个字段存放整个消息包的字节数。

如果消息包采用字符串格式,这个描述长度的字段本身就是一个可变的字符串,它的位数会影响到消息包的长度。例如,我们定义了如下的消息包格式:

# msg_len , msg_content $

这个消息包的格式,非常简单,首先以 '# '字符开头,然后是 msg_len即整个消息包的长度,接着是逗号 ',',接着是消息的内容 msg_content,最后以‘ $’字符结尾。例如,下面就是一个整体长度为 9,消息内容为“ china”的消息包:

#9,china$

那么,编程的时候,如何求出这个 msg_len呢?因为 msg_len本身以字符串表示,随着消息内容的长度变化, msg_len的位数也在变化,由于 msg_len本身也是消息的一部分,因此在计算 msg_len时,还要把 msg_len本身的位数也考虑进去。

试看这两种情况,

  1. 假如除了 msg_len之外的其余部分的长度为 7,那么 msg_len字段值应为 8。因为 msg_len本身( '8')占一个字符长度,再加上 7,所以长度是8
  2. 假如除 msg_len之外的其余部分的长度为 9,那么 msg_len字段的值应为 11。因为 msg_len本身(‘ 11’)占两个字符长度,再加上 9,所以长度是 11。

msg_len的值为 y,设 w(x)表示求取 x的位数,设消息包除了 msg_len之外的其余部分的长度为 x。那么 y满足如下关系:

  • 如果 x+w(x)的值的位数,与 x的位数一样,则 y=x+w(x)
  • 如果 x+w(x)的值的位数,比 x的位数多 s位,则 y=x+w(y)

第二个式子很难求解,但凭感觉,貌似以下结论成立:

x+w(x)的位数,不可能比 w(x)大1(其等于 w(x) w(x)+1)。

以下是我的证明,采用反证法:假设存在一个 x,使 x+w(x)的位数比 w(x) 1,设:

x=XnXn-1...X1X0, 则有:

XnXn-1...X1X0 + (n+1) >= X'(n+2)X'(n+1)...X'1X'0                                            =>

max( XnXn-1...X1X0) + (n+1) >= min(X'(n+2)X'(n+1)...X'1X'0)                       =>

10^(n+1) – 1 + (n+1) >= 10^(n+2)                                                                         =>

n >= 10^n * 90

显然,这样的 n不可能存在。证明完毕!

基于这个结论,填写消息包的长度时,程序就可以轻松处理了:

  • 如果 x+w(x)的值的位数,与 x的位数一样,则 y=x+w(x)
  • 如果 x+w(x)的值的位数,比 x的位数大 (由前面的结论,只可能进一位 ),则 y=x+w(x)+1 (因为 x+w(x)已经进了一位,可以证明 x+w(x)+1不会再进一位)。

以下是C语言实现的代码:

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值