专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »游戏开发 » 电学线路连接的要点:tcp要点学习-建立连接 »正文

电学线路连接的要点:tcp要点学习-建立连接

来源: 发布时间:星期四, 2009年2月12日 浏览:84次 评论:0


有关WinDump具体使用方法你可以从网上其他地方获取这里我只稍微提要让WinDump开始监听数据
首先需要确定让其监听哪个网络设备(或者说是网络接口)你可以:

windump -D

获取当前机器上网络接口然后使用:

windump -i 2

开始对网络接口2数据监听windump如同tcpdump(其实就是tcpdump)样支持过滤表达式windump
将会根据你提供过滤表达式过滤不需要网络数据包例如:

windump -i 2 port 4000
那么windump只会显示端口号为4000网络数据

序号和确认号:

要讲解TCP建立过程也就是那个所谓 3次握手就会涉及到序号和确认号这两个东西翻书到TCP 报文头有两个很重要域(都是32位)就是序号域和确认号域可能有些同学会对TCP那个报文头有所 疑惑(能看懂我在讲什么会产生这样疑惑么?)这里我可以告诉你你可以假想TCP报文头就是个 C语言结构体(假想而已去翻翻bsd对TCP实现肯定没这么简单)那么大致上所谓TCP报文头就是:


typedef struct _tcp_header
{
/**//// 16位源端口号
unsigned src_port;
/**//// 16位目端口号
unsigned dst_port;
/**//// 32位序号
unsigned long seq_num;
/**//// 32位确认号
unsigned long ack_num;
/**//// 16位标志位[4位首部长度保留6位ACK、SYN的类标志位]
unsigned flag;
/**//// 16位窗口大小
unsigned win_size;
/**//// 16位校验和
crc_sum;
/**//// 16位紧急指针
ptr;
/**//// 可选选项
/// how to implement this ?
} tcp_header;


那么这个序号和确认号是什么?TCP报文为每个字节都设置个序号觉得很奇怪?这里并不是为每 字节附加个序号(那会是多么可笑编程手法?)而是为个TCP报文附加个序号这个序号表示报文 中数据个字节序号而其他数据则是根据离第个数据偏移来决定序号例如现在有数据: abcd如果这段数据序号为1200那么a序号就是1200b序号就是1201而TCP发送个数据包 序号就会是上个数据包最后个字节序号加例如efghi是abcd个数据包那么它序号就 是1204通过这种看似简单思路方法TCP就实现了为每个字节设置序号功能(终于明白为什么书上要告诉 我们‘为每个字节设置个序号’了吧?)注意设置序号是种可以让TCP成为’可靠协议‘手段 TCP中各种乱 7 8糟东西都是有目大部分目还是为了’可靠‘两个字别把TCP看高深了如果 让你来设计个网络协议需要告诉你是’可靠你就会明白为什么会产生那些乱 7 8糟东西了

接着看确认号是什么?TCP会对接收到数据包进行确认发送确认数据包时就会设置这个确认号 确认号通常表示接收方希望接收到段报文序号例如某次接收方收到序号为12004字节数举报 那么它发送确认报文给发送方时就会设置确认号为1204

大部分书上在讲确认号和序号时都会说确认号是序号加这其实有点误解人所以我才在这里废话了 半天(高手宽容下:D)

开始 3次握手:

如果你还不会简单tcp 编程我建议你先去学学这就好比你不会C基本语法就别去研究vtable 的类

3次握手开始于客户端试图连接服务器端当你诸如connect正常情况下就会开始 3次握手 随便在网上找张 3次握手图:





如前文所述 3次握手也就是产生了 3个数据包客户端主动连接发送SYN被设置了报文(注意序号和 确认号这里不包含用户数据所以序号和确认号就是加关系)服务器端收到该报文时正 常情况下就发送SYN和ACK被设置了报文作为确认以及告诉客户端:我想打开我这边连接(双工)客户 端于是再对服务器端SYN进行确认于是再发送ACK报文然后连接建立完毕对于阻塞式而言connect可能就返回成功给你

在进行了铺天盖地罗利巴索基础概念讲解后看看这个连接建立过程是不是简单得几近无聊?

我们来实际点写个最简单客户端代码:


sockaddr_in addr;
mem( &addr, 0, ( addr ) );
addr.sin_family = AF_INET;
addr.sin_port = htons( 80 );
/**//// 220.181.37.55
addr.sin_addr.s_addr = inet_addr( "220.181.37.55" );
prf( "%s : connecting to server.\n", _str_time );
err = connect( s, (sockaddr*) &addr, ( addr ) );


主要就是connect运行前我们运行windump:



windump -i 2 host 220.181.37.55


00:38:22.979229 IP noname.do.4397 > 220.181.37.55.80: S 2523219966:2523219966(0) win 65535 <mss 1460,nop,nop,sackOK>
00:38:23.024254 IP 220.181.37.55.80 > noname.do.4397: S 1277008647:1277008647(0) ack 2523219967 win 2920 <mss 1440,nop,nop,sackOK>
00:38:23.024338 IP noname.do.4397 > 220.181.37.55.80: . ack 1 win 65535




如何分析windump结果建议参看<tcp/ip详解>中对于tcpdump描述

建立连接附加信息:

虽然SYN、ACK的类报文没有用户数据但是TCP还是附加了其他信息最为重要就是附加MSS值这个可以被协商MSS值基本上就只在建立连接时协商如以上数据表示MSS为1460字节

连接意外:

连接意外我大致分为两种情况(也许还有更多情况):目主机不可达、目主机并没有在指定端口监听 当目主机不可达时也就是说SYN报文段根本无法到达对方(如果你机器根本没插网线你就不可达) 那么TCP收不到任何回复报文这个时候你会看到TCP中定时器机制出现了TCP对发出SYN报文进行 计时当在指定时间内没有得到回复报文时TCP就会重传刚才SYN报文通常各种区别TCP实现对于 这个超时值都区别但是据我观察重传次数基本上都是3次例如我连接个不可达主机:



12:39:50.560690 IP cd-zhangmin.1573 > 220.181.37.55.1024: S 3117975575:3117975575(0) win 65535 <mss 1460,nop,nop,sackOK>
12:39:53.538734 IP cd-zhangmin.1573 > 220.181.37.55.1024: S 3117975575:3117975575(0) win 65535 <mss 1460,nop,nop,sackOK>
12:39:59.663726 IP cd-zhangmin.1573 > 220.181.37.55.1024: S 3117975575:3117975575(0) win 65535 <mss 1460,nop,nop,sackOK>


发出了 3个序号SYN报文但是没有得到个回复报文(废话)个SYN报文的间间隔时间都是 有规律在windows上是3秒6秒9秒12秒上面数据你看不到12秒这个数据这是第 3个报文发出 时间和connect返回信息时时间的差方面如果连接同个网络这个间隔时间又区别例如直接连局域网间隔时间就差不多为500ms

(我强烈建议你能运行windump去试验这里提到个现象如果你在ubuntu下使用tcpdump记住sudo :D)



出现意外第 2种情况是如果主机数据包可达但是试图连接端口根本没有监听那么发送SYN报文这方会收到RST被设置报文(connect也会返回相应信息给你)例如:



13:37:22.202532 IP cd-zhangmin.1658 > 7AURORA-CCTEST.7100: S 2417354281:2417354281(0) win 65535 <mss 1460,nop,nop,sackOK>
13:37:22.202627 IP 7AURORA-CCTEST.7100 > cd-zhangmin.1658: R 0:0(0) ack 2417354282 win 0
13:37:22.711415 IP cd-zhangmin.1658 > 7AURORA-CCTEST.7100: S 2417354281:2417354281(0) win 65535 <mss 1460,nop,nop,sackOK>
13:37:22.711498 IP 7AURORA-CCTEST.7100 > cd-zhangmin.1658: R 0:0(0) ack 1 win 0
13:37:23.367733 IP cd-zhangmin.1658 > 7AURORA-CCTEST.7100: S 2417354281:2417354281(0) win 65535 <mss 1460,nop,nop,sackOK>
13:37:23.367826 IP 7AURORA-CCTEST.7100 > cd-zhangmin.1658: R 0:0(0) ack 1 win 0


可以看出7AURORA-CCTEST.7100返回了RST报文给我但是我这边根本不在乎这个报文继续发送SYN报文 3次过后connect就返回了(数据反映事实是这样)

有关listen:

TCP服务器端会维护个新连接队列当新连接上客户端 3次握手完成时就会将其放入这个队列这个队

大小是通过listen设置当这个队列满时如果有新客户端试图连接(发送SYN)服务器端丢弃报文

同时不做任何回复

整理总结:
TCP连接建立相关要点就是这些(or more?)正常情况下就是 3次握手非正常情况下就是SYN 3次超时
以及收到RST报文却被忽略
标签:
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: