Linux TCP_DEFER_ACCEPT的作用

1. TCP服务端

        int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
        ......
        bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr));
	listen(serverSocket, 5);
	
	while(1)
	{
		int client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);
                
		while(not_finished)
		{
			iDataNum = recv(client, buffer, 1024, 0);
			//process the data received...
		}
	}

2. 连接的建立


client                                   server

      --------------SYNC--------------->>

      <<----------SYNC/ACK---------------

      ---------------ACK--------------->>  accept() returns, but blocks on recv() immediately;


3. 对于HTTP

其实1中的TCP服务端的例子和HTTP服务端很像:建立连接后,立即读数据(读取HTTP请求)。在这种情况下,client发出ACK之后,server被唤醒(accept返回),并立即试图读数据,由于client还没有发数据,server又再度阻塞。这对于调度是一种浪费。另外,client发的那个ACK也没有实际作用,是不必要的。

假如server端内核忽略client发的ACK,而直接等待数据,数据收到之后再唤醒serve(accept返回),server醒来后就可以直接得到数据并处理。这就是TCP_DEFER_ACCEPT的作用。

server端的socket fd是处于listen状态的,设置TCP_DEFER_ACCEPT之后,内核就会忽略ACK,接收到数据之后再唤醒server(accept返回)。

另外,试想,既然server端忽略ACK,那么客户端可不可以不发送ACK,而直接发送数据呢,这样就节省了一次传输?答案是可以的:TCP_DEFER_ACCEPT设置在client端的socket fd上,就能达到这个效果。

问题:客户端如何知道服务端设置了TCP_DEFER_ACCEPT呢?假如服务端没有设置,而自己设置了,会不会出错?我猜应该不会出错,client本该使用序列号X发送ACK,现在使用序列号X直接发送数据,也符合TCP协议

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值