之前对listen、accpet函数理解误区----《Linux高性能服务器编程》读书笔记

    以前一直以为TCP建立连接3次握手过程服务端是对应accept函数调用,看了《Linux高性能服务器编程》才发现以前理解有误。服务端建立了监听端口就可以接受客户端连接。服务端调用listen函数来创建一个监听队列以存放待处理的客户连接。其中第二个参数backlog表示内核监听队列最大长度,也就是完全连接状态(established)的socket上限,实际上是backlog+1。

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


static bool stop = false;
// SIGTERM handler func
static void handle_term( int sig )
{
	stop = true;
}


int main( int argc, char* argv[] )
{
	signal( SIGTERM, handle_term );
	
	if( argc < 3 )
	{
		printf("usage: %s ip port [backlog]\n", argv[0]);
		return 1;
	}
	
	const char* ip = argv[1];
	int port = atoi(argv[2]);
	int backlog = 5;
	if( argc > 3)
	{
		backlog = atoi(argv[3]);
	}
	
	int fd_listen = socket( PF_INET, SOCK_STREAM, 0 );
	assert( fd_listen >= 0 );
	
	struct sockaddr_in svr_addr;
	bzero( &svr_addr, sizeof(svr_addr) );
	svr_addr.sin_family = AF_INET;
	inet_pton( AF_INET, ip, &svr_addr.sin_addr );
	svr_addr.sin_port = htons( port );
	
	int ret = bind( fd_listen, (struct sockaddr*)&svr_addr, sizeof(svr_addr) );
	assert( ret != -1 );
		
	ret = listen( fd_listen, backlog );
	assert( ret != -1 );
	printf(" server listening [%s:%d]\n", ip, port);
	
	while( !stop )
	{
		sleep( 1 );
	}
	
	close( fd_listen );
	
	return 0;
}
 

运行服务端:默认backlog为5


开启多个nc连接服务端:



nc大于6个后,后面的连接状态就是SYN_RECV,说明最多建立backlog+1个完整连接。

accept函数只是从监听队列取出连接,不论连接处于何种状态(ESTABLISHED,CLOSE_WAIT),更不关心任何网络状况的变化。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值