摘要
本文主要分析linux网络开发中关于listen函数的backlog参数的设置对于编程的影响。从eth接口和loopback接口看其在连接队列满后对新连接的处理情况。
本文测试环境基于VMWare上的Centos 7。
1, client端
client端调用connect函数向server端发送sync包,当服务器收到sync包并回给sync+ack后服务器的状态变为syn_recv状态,
client收到syn+ack后状态就变成了ESTABLISHED状态。此时客户端认为连接建立成功了,connect成功返回。
2,server端
server端调用listen后,listen socket转为被动状态(即等待连接)。而listen的backlog指定了这个被动状态的socket的未连接队列和已连接队列的长度。本文主要探讨backlog对建立连接的影响。当服务器端收到客户端三步握手协议的最后一个ack时,会把处于sync_recv状态的socket从未连接队列移除放入已连接队列(ESTABLISHED)队列中,此时accept函数返回。
3,服务器端测试程序
服务器程序故意在listen后进入死循环,即不从ESTABLISHED队列把完成握手的socket移除,以便于查看。
int main()
{
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12345);
server_addr.sin_addr.s_addr = INADDR_ANY;
int listen_fd = socket(PF_INET, SOCK_STREAM, 0);
if(listen_fd == -1){
perror("create socket");
return -1;
}
if(bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))== -1){
perror("bind");
return -1;
}
if(listen(listen_fd, 5) == -1) {
perror("listen");
return -1;
}
//while(1)
//{
// sleep(50000);
// struct sockaddr_in client_addr;
// socklen_t len;
// int client_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &len);
//}
while(1){
int a = 0;
a = a + 1;
}
return 0;
}
4,实验结果
4.1,使用loopba