怎样计算TCP报头的CheckSum值?(30分)

  • 主题发起人 主题发起人 eehuang
  • 开始时间 开始时间
E

eehuang

Unregistered / Unconfirmed
GUEST, unregistred user!
请问各位有谁知道怎样计算TCP报头的CheckSum(16位的校验和)值?
我是这样算的----所有(包括报头和数据包的项)的16位的和取反,但
是好象不对。(希望能给一数学公式)
 
”16位“肯定不对,应是8位。
 
1.将CheckSum域置0再计算
2.计算TCP的CheckSum时要<H3>包括</H3>数据域
3.以16位为单位
4.用"异或",不是"和"
5.最后取反
 
我以前说错了。
现给出正确的:
TCP的CHECKSUM 只对TCP的头进行校验。
TCP的头长度位于TCP包的4-8的位。
头长度应是32位的整数倍。
校验前将CheckSum清0。
以16位为单位,求异或,再取反。
 
IP的CheckSum才只对头进行计算,TCP是需要对数据域参加运算的!
 
如果没有其他讨论
eehuang,请结束此问题吧

 
没这么简单,好好算,注意进位
 
按16位一组,取补码相加,然后对和取补码
在计算过程中,应包括TCP的伪头。
详细内容,请参阅有关TCP/IP的书籍。
 
我把用liling的ipmandelphi改编的tcp头的checksum部分发给你
吧,希望能对你有用:
pTCPHead.SourPort:=swaps(sourport);
pTCPHead.DestPort:=swaps(destport);
pTCPHead.SeqNo:=swapl(seqno);
pTCPHead.AckNo:=swapl(ackno);
pTCPHead.HLen:=TCP_HEAD_LEN shl 4;
pTCPHead.Flag:=flag;
pTCPHead.WndSize:=swaps(8192);
pTCPHead.UrgPtr:=0;
ptcphead.ChkSum:=0;
move(pdata,pbuf,len);

// Calculate TCP checksum

seudoHead.SourIP:=psourip;
seudoHead.DestIP:=pdestip;
seudoHead.Pad:=0;
seudoHead.Proto:=IP_PROTO_TCP;
wlen:=len+TCP_HEAD_BYTE_LEN;
seudoHead.Len:=swaps(wlen);
for i:=1 to wlen do helpbuffer[PSEUDO_HEAD_LEN+i]:=buffer[ETHER_HEAD_LEN+IP_HEAD_BYTE_LEN+i];
wlen:=len+TCP_HEAD_BYTE_LEN+PSEUDO_HEAD_LEN;
pTCPHead.ChkSum:=CheckSum(pword(@HelpBuffer),wlen);


其实也就是部分IP头加上Tcp加上数据部分的总校验和。
 
说的再清楚些好吗
 
以下是我以前的代码,c++ builder的
USHORT __fastcall TForm1::checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;

while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size)
cksum += *(UCHAR*)buffer;
cksum = (cksum >> 16) + (cksum &amp; 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
 
wwwsys的checksum计算算法是正确的。

但是要注意TCP的checksum要加上一个
pseudo header.这个header有12个字节
长度,头四个是Source IP,再下来四个
是Destination IP,接下来一个字节是
0,然后是一个6(一字节),表示是一个
TCP包,再是TCP包的长度,这个长度是
包括了TCP包头的。

这些东西都是network byte order, 所以
要调用htonl和htons这样的函数。

另外在计算checksum之前,checksum要置
为0.
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部