我想自己模拟TCP协议三次握手的过程,用的是WinPcap,手动建立 以太帧头结构,IP头结构,最后封装到TCP包,再发送出去,想要连接到一个网站,比如百度。我的本机IP为 202.108.1.166:1000。百度的IP为 202.108.22.5 :80.
之后我开始用ethereal抓包。我第一次建了一个TCP的【seq】包。seq = 0,ack = 0, 可以收到百度发回来的【seq,ack】包。seq = 0 ,ack = 1;再后来我想发了一个应答包确认连接,可是系统每次都直接发送了。但是好像并不能连接成功,系统发了一个seq = 1,ack = 323424242 后面那个反正是很大,很乱的一个数。应该是错误的吧。
    之后我又做了一些改版。我把我发送的包的我的IP都改成了 202.108.1.165:1000 为了能收到百度发回的确认包,我又向网关发送了一条ARP应答包。把我的mac绑定到了165这个IP上面。我便可以接收到百度的确认包,同时,系统也不再自动发包应答。我便自己又建了一个TCP的【ack】包。我在程序里,将seq =1,ack = 1;(这些值我用的是IE打开百度网页时我抓包,其中开始时连接百度的三次握手中 三次的 seq,ack值)。但是问题出现了,我抓包时,前两次正常,而第三次我发的确认包就是有问题。我明明seq,和ack设置的是完全一样的值,但是抓包时,就是显示,seq = 1,ack = 1327364239(一个无规律的大数,而且每次都不通)有时还提示,上一个应答段丢失什么的。这个问题让我非常的费解。已经困扰十天左右了,就是找不到什么原因。请问各位,难道不能像我这样手动发包实现TcP连接吗?
若是可以的话,第三次我发确认包的时候。除了在 序列号 和 确认号 上与上一个包有联系之外,还有什么与之前包必须关联的数据位码?
我这问题可能错在哪里了呢?为什么第三个包ack我明明设置的是和seq完全一样的值,但是抓吧就是现实乱的值呢?
这样的结果  tcp连接应该是没有建立成功吧?
 
下面是我定义的协议头部结构
//以太帧  头部信息
typedef struct _EhternetHeader
{
u_char DestMac[6];     //目的MAC地址
u_char SourMac[6];     //源MAC地址
u_short EthType;         //帧类型
}EhternetHeader,*PEhternetHeader;
 
//ARP协议  头部信息
typedef struct _ArpHeader
{
u_short HardwareType;            //硬件类型
u_short ProtocolType;             //协议类型
u_char  MacLength;                //硬件地址长度
u_char  IpAddLength;              //协议地址长度
u_short OperationCode;             //操作类型
u_char  SourMac[6];                 //发送端MAC地址
u_char  SourIP[4];                 //发送端IP地址
u_char  DestMac[6];                 //目的MAC地址
u_char  DestIP[4];                 //目的IP地址
}ArpHeader,*PArpHeader;
 
//IP协议  头部信息
typedef struct _IPHeader
{
u_char Versino_HLen;             //首部长度 IP版本号
u_char TOS;                         //服务类型TOS
short  totalLength;                 //总长度
short  Ident;                         //标识
short  Flags_Offset;                 //标志位
u_char TTL;                         //生存时间 TTL
u_char ProtocolType;                 //协议
short  CheckSum;                 //IP首部校验和
u_int  SourAddr;                 //源IP地址
u_int  DestAddr;                 //目的IP地址
}IPHeader,*PIPHeader;
 
//TCP协议  头部信息
typedef struct _TCPHeader
{
u_short SourPort;                     //16位源端口
u_short DestProt;                     //16位目的端口
u_int SequenceNum;                 //32位序号
u_int Acknowledgment;             //32位确认序号
u_char HeaderLength;             //首部长度
u_char Flags;                         //6位标志位
u_short AdvertisedWindow;     //16位窗口大小
u_short CheckSum;                    //16位校验和
u_short UrgPtr;                     //16位紧急指针
}TCPHeader,*PTCPHeader;
 
会是头部信息定义有问题吗?

解决方案 »

  1.   

    你的是 Windows吧? 人家是 Unix..注意字节序
      

  2.   

    请问各位,难道不能像我这样手动发包实现TcP连接吗?
    答:可以发包连接。若是可以的话,第三次我发确认包的时候。除了在 序列号 和 确认号 上与上一个包有联系之外,还有什么与之前包必须关联的数据位码?
    答:依据TCP头部来做。我这问题可能错在哪里了呢?为什么第三个包ack我明明设置的是和seq完全一样的值,但是抓吧就是现实乱的值呢?
    这样的结果  tcp连接应该是没有建立成功吧?
    答:你的程序代码错误,例如 网络字节与主机字节的转换。
      

  3.   

    tcp连接三次握手是个问题,搞的我也总是出现异常,有时间要细致看看!
      

  4.   

    windows linux 协议栈自动回复ack,此题无解。保证无解。winpacp也一样,他得过协议栈,
    想在应用层测试三次握手只有unix可以做到,如果想在windows linux dos等等系统下做,只有绕开协议栈。结贴给分吧:)
      

  5.   

    Mark一下,有空 也想写一个握手程序