我想自己模拟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;
会是头部信息定义有问题吗?
之后我开始用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;
会是头部信息定义有问题吗?
答:可以发包连接。若是可以的话,第三次我发确认包的时候。除了在 序列号 和 确认号 上与上一个包有联系之外,还有什么与之前包必须关联的数据位码?
答:依据TCP头部来做。我这问题可能错在哪里了呢?为什么第三个包ack我明明设置的是和seq完全一样的值,但是抓吧就是现实乱的值呢?
这样的结果 tcp连接应该是没有建立成功吧?
答:你的程序代码错误,例如 网络字节与主机字节的转换。
想在应用层测试三次握手只有unix可以做到,如果想在windows linux dos等等系统下做,只有绕开协议栈。结贴给分吧:)