accept() -- 从监听队列中取出连接

今天在《Linux高性能服务器编程》中看到:accept()函数是从监听队列中取出连接,于是自己使用书上的方法验证了一下,代码如下:

//accept_abnor_data.cpp

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char * argv[]) {
    if (argc <= 2) {
        printf("usage:%s ip_address port_number\n", argv[0]);
        return 1;
    }
    const char * ip = argv[1];
    int port = atoi(argv[2]);

    struct sockaddr_in address;
    bzero(&address, sizeof(address));
    address.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &address.sin_addr);
    address.sin_port = htons(port);

    int sock = socket(PF_INET, SOCK_STREAM, 0);
    assert(sock >= 0);

    int ret = bind(sock, (struct sockaddr *)&address, sizeof(address));
    assert(ret != -1);

    ret = listen(sock, 5);
    assert(ret != -1);

    sleep(20); //睡眠20s

    struct sockaddr_in client;
    socklen_t client_addrlength = sizeof(client);

    int connfd = accept(sock, (struct sockaddr *)&client, &client_addrlength);  //accept()是从监听队列中取出连接,不论连接状态如何
    if (connfd < 0) {
        printf("errno is: %d\n", errno);     
    }
    else {
        //接受成功打印客户端ip和端口号
        char remote[INET_ADDRSTRLEN];
        printf("connected with ip :%s and port :%d\n", 
            inet_ntop(AF_INET, &client.sin_addr, remote, INET_ADDRSTRLEN), ntohs(client.sin_port));
    }

    return 0;
}

修改Makefile结果如下:

.PHONY:clean all
CC=gcc
GFLAGS=-Wall -g
BIN=accept_abnor_data
all:$(BIN)
%.0:%.c
    $(CC) $(GFLAGS) -c $< -o $@
clean:
    rm -f *.o $(BIN)

打开终端(1),执行下列命令:

make
./accept_abnor_data 192.168.1.104 12345

打开另一个终端(2),使用telnet命令进行登录:

telnet 192.168.1.104 12345

结果如下:
这里写图片描述
再打开一个终端终端,查看端口状态:

netstat -nt | grep 12345

查看到网络状态如下:
这里写图片描述
终端(1)中的./accept_abnor_data 192.168.1.104 12345命令执行20后,即睡眠结束,终端(1)上会打印出:

这里写图片描述
终端(2)上会打印出:
这里写图片描述
以上是客户端正常退出的结果,下面我们来看一下客户端异常退出的情况:
操作与上面不同的是,我们在终端使用telnet远程登录时(测试是在本地进行的),登录成功后,键入ctrl+],强制退出到telnet命令界面,再键入quit命令,结果如下:
这里写图片描述
客户端已经退出,此时的端口状态为:
这里写图片描述
客户端和服务器端端口状态分别为:FIN_WAIT2 、CLOSE_WAIT
此时,你能以为服务器端不会接受客户端的本次连接了,可等到服务器端睡眠20s后,仍能接受客户端的请求,并打印客户端的ip和端口号:
这里写图片描述

由此可见,accept()函数只是从监听队列中取出连接,并不关心连接处于何种状态,更不关心任何网络状况的变化,只要监听队列中有请求连接,服务器端就可以进行连接。

注:测试是在本地进行的,本地ip为192.168.1.104

参考:
《高性能服务器编程》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值