TCP/IP的状态转换图


TCP/IP的状态转换图_第1张图片

《Unix网络编程》 图2.4

int main(int argc, char *argv[])
{
    int listenfd, clifd;
    socklen_t clilen;
    pid_t childpid;
    struct sockaddr_in seraddr, cliaddr;
    listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    bzero(&seraddr, sizeof(seraddr));
    seraddr.sin_family = AF_INET;
    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    seraddr.sin_port = htons(SER_PORT);
    Bind(listenfd, (SA*)&seraddr, sizeof(seraddr));
    Listen(listenfd, 5);
    fprintf(stderr, "I'm listening on port %d ...\n", SER_PORT);
    for(;;)
    {
        clifd = Accept(listenfd, (SA *)&cliaddr, &clilen);
        str_echo(clifd);
        /*
        sleep(1);        
        exit(-1);    睡眠1秒后退出进程,但是服务器进程就退出了
        */
    }
}

        在上面的代码(《Unix网路编程》Echo服务器,改成了单进程版,只能处理一个连接,服务器功能在str_echo()中体现,做的是单纯的echo客户端发送的数据,读取到EOF是返回)中,服务器代码阻塞于accept()函数的调用中。当有连接时,str_echo调用,读到EOF时(此时客户端关闭),客户端进程结束,发送一个FIN(尽管状态图上是FIN,但实际上应该是FIN、ACK,抓包可以验证这点。TCP/IPV1书中也是FIN、ACK)给当前服务器,从状态图可以看到,客户端进入到FIN_WAIT_1,而服务器收到FIN后,回应ACK,自己则进入CLOSE_WAIT状态。有状态图可知,客户端接收FIN后,自己进入到FIN_WAIT_2状态。从代码可以看到,此时服务端进程没有关闭,索引服务端一直在CLOSE_WAIT的状态,这个状态会持续大约2小时左右(和系统有关)。如果此时服务端进程关闭。那么服务端发送一个FIN(FIN、ACK),服务端进入到LAST_ACK,客户端收到后发送ACK,进入到TIME_WAIT(状态)。到此四次挥手完成!但是上面代码,服务器会卡在CLOSE_WAIT的状态。

        具体的状态和服务器、客户的关系不太大,主要关系在主动关闭方,和被动关闭方。

































你可能感兴趣的:(TCP/IP的状态转换图)