前面讲到过,UDP socket和RAW
socket上的connect调用的原理是相当简单的,它所做的操作只是通过路由规则和路由表等一些信息,在struct
socket结构中填入一些有关对端服务器的信息,这样,以后向对端发送数据报时,就不需要每次进行路由查询等操作以确定对端地址信息和本地发送接口,应
用程序也就不需要每次传入对端地址信息(可以使用send而不使用sendto)。这也就是为什么UDP被称为无连接的协议。
但TCP socket上的connect系统调用就相对比较复杂了,下面我们逐步探索tcp socket上的connect系统调用的流程,及涉及到的一些相关的数据结构。
tcp
socket的connect系统调用首先到达的函数是myinet_stream_connect,它首先判断套接字的当前状态,并根据当前的状态决定
下一步要执行的动作。在代表套接口的结构体struct socket中有一个成员state,它表示当前套接口所处的连接状态,该成员只对tcp
socket有意义,因为只有tcp是面向连接的协议。其可能的取值如下:
typedef enum {
SS_FREE = 0, //未创建
SS_UNCONNECTED, //未连接到任何socket
SS_CONNECTING, //正在接接过程中
SS_CONNECTED, //已连接
SS_DISCONNECTING //正在断开连接之中
} socket_state;
在一个socket被创建的时候,其状态应该是SS_UNCONNECTED,myinet_stream_connect调用tcp协议的连接函数
mytcp_v4_connect完成socket的一些本地设置后,将这个状态改为SS_CONNECTING。然后调用
myinet_wait_for_connect建立到对端的连接,连接成功,则将状态改为SS_CONNECTED,connect成功。
代表网络层套接口的结构体struct sock也有一个成员sk_state,它表示的是TCP套接口的工作状态,其可能的取值如下:
enum {
TCPF_ESTABLISHED = (1 << 1),
TCPF_SYN_SENT = (1 << 2),
TCPF_SYN_RECV = (1 << 3),
TCPF_FIN_WAIT1 = (1 << 4),
TCPF_FIN_WAIT2 = (1 << 5),
TCPF_TIME_WAIT = (1 << 6),
TCPF_CLOSE = (1 << 7),
TCPF_CLOSE_WAIT = (1 << 8),
TCPF_LAST_ACK = (1 << 9),
TCPF_LISTEN = (1 << 10),
TCPF_CLOSING = (1 << 11)
};
在tcp socket建立之初,其状态为TCPF_CLOSE,准备建立到对端的连接之前,被改为TCP_SYN_SENT。
阅读(274) | 评论(0) | 转发(0) |