基本概念
1.TCP连接的三路握手
简要说明:
- 服务器必须准备好接受外来的连接,这通过调用socket、bind和listen函数完成,称为被动打开(passive open);
- 客
户通过调用connect进行主动打开(active
open),这引起客户TCP发送一个SYN分节(表示同步),它告诉服务器客户将在(待建立)连接中发送的数据的初始序列号。一般情况下SYN分节不携
带数据,它只含有一个IP头部、一个TCP头部以及可能有的TCP选项;
- 服务器必须确认客户的SYN,同时自己也得发送一个SYNV分节,它含有服务器将在同一连接中发送数据的初始序列号。服务器以单个分节向客户发送SYN和对客户SYN的ACK;
- 客户必须确认服务器的SYN。
2.TCP关闭的四个分节
简要说明:
- 一端的应用程序首先调用close,称这端执行主动关闭(active close)。这端的TCP于是发送一个FIN分节,表示数据发送完毕;
- 接收到FIN的另一端执行被动关闭(passive close)。这个FIN由TCP确认,它的接收也作为文件结束符传递给接收方应用程序(放在已排队等候应用程序接收的任何其他数据之后),因为FIN的接收意味着应用程序在相应连接上再也接收不到额外数据;
- 一段时间后,接收到FIN文件结束符的应用程序将调用close关闭它的套接口,这导致它的TCP也发送一个FIN;
- 接收到这个FIN的原发送方TCP(即执行主动关闭的那一端)对它进行确认。
3.TCP连接的11种状态极其相互转换
简要说明:
(1).起始状态(CLOSED)
服务器被动打开,进入LISTEN状态;
客户主动打开,发送SIN分节,进入SYN_SENT状态;
(2).被动打开状态(LISTEN)
接收到SYN分节,发送ACK,发送SYN后,进入SYN_RCVD状态;
(3).主动打开状态(SYN_SENT)
应用close或超时,则返回CLOSED状态;
接收到SYN,发送ACK,发送SYN(同时打开),进入SYN_RCVD状态;
接收到SYN,ACK,发送ACK后,进入ESTABLISHED状态;
(4).SYN_RCVD状态
接收到ACK,则进入ESTABLISHED状态;
接收到RST,则返回到LISTEN状态;
(5).数据传输状态(ESTABLISHED)
接收到FIN,发送ACK,进入CLOSE_WAIT状态;
应用close,发送FIN,进入FIN_WAIT_1状态;
(6).CLOSE_WAIT状态
应用close,或发送FIN,进入LAST_ACK状态;
(7).LAST_ACK状态
接收到ACK,则返回到起始状态(CLOSED);
(8).FIN_WAIT_1状态
接收到FIN,发送ACK,进入同时关闭状态(CLOSING);
接收到ACK,进入FIN_WAIT_2状态;
接收到FIN,ACK,发送ACK,进入TIME_WAIT状态;
(9).同时关闭状态(CLOSING)
接收到ACK,进入TIME_WAIT状态;
(10).FIN_WAIT_2状态
接收FIN,发送ACK,进入TIME_WAIT状态;
(11).TIME_WAIT状态
经过2MSL超时,返回初始状态(CLOSED);
4.IPv4套接口地址结构
struct in_addr {
in_addr_t s_addr;
/* 32-bit IPv4 address,network byte ordered*/
};
struct sockaddr_in {
uint8_t sin_len;
/* length of structure(16) */
sa_family_t sin_family;
/* AF_INET */
in_port_t sin_port;
/* 16-bit TCP or UDP port number,network byte ordered */
struct in_addr sin_addr;
/* 32-bit IPv4 address,network byte ordered */
char sin_zero[8];
/* unused */
};
注意事项:
- 我们一般只使用三个成员:sin_family、sin_addr和sin_port;
- IPv4地址和端口号在结构中总是以网络字节序存储;
- 一般在使用前,将整个结构初始化为0。
5.通用套接口地址结构
struct sockaddr {
uint8_t sa_len;
sa_family_t sa_family;
/* address family:AF_xxx */
char sa_data[14];
/* protocol-spacial address */
};
6.IPv6套接口地址结构
struct in6_addr {
uint8_t s6_addr[16];
/* 128-bit IPv6 address,network byte ordered */
};
#define SIN6_LEN /* required for compile-time tests */
struct sockaddr_in6 {
uint8_t sin6_len;
/* length for this struct(24) */
sa_family_t sin6_family;
/* AF_INET6 */
in_port_t sin6_port;
/* transport layer port,network byte ordered */
uint32_t sin6_flowinfo;
/* priority and flow label */
struct in6_addr sin6_addr;
/* IPv6 address,network byte ordered */
};
注意事项:
- 如果系统支持套接口地址结构中的长度成员,则SIN6_LEN常值必须定义;
- IPv6地址族是AF_INET6,而IPv4地址族是AF_INET;
- 结构中的成员是有序排列的。
7.其他数据类型
名称 |
说明 |
int8_t |
带符号的8位整数 |
uint8_t |
无符号的8位整数 |
int16_t |
带符号的16位整数 |
uint16_t |
无符号的16位整数 |
int32_t |
带符号的32位整数 |
uint32_t |
无符号的32位整数 |
sa_family_t |
套接口地址结构的地址族 |
socklen_t |
套接口地址结构的长度,一般为uint32_t |
in_addr_t |
IPv4地址,一般为uint32_t |
in_port_t |
TCP或UDP端口,一般为uint16_t |