友链
references:
具体使用就是SO_REUSEPORT选项
这个选项允许多个套接字绑定到同一个地址和端口上
该选项的主要目的就是为了提升多线程网络服务器应用的性能
int sfd = socket(domain, socktype, 0);
int optval = 1;
setsockopt(sfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
bind(sfd, (struct sockaddr *) &addr, addrlen);
只要绑定到这个地址和端口上的套接字都设置了SO_REUSEPORT
选项,那么他们就可以绑定到同一个地址和端口
这样不同线程中的socket就可以使用自己的套接字来调用accept函数来接收客户端数据,在这之前,多线程服务器应用中所有的线程都是用同一个套接字调用accept
对于以前的单套接字方式,如果来自客户端的流量特别大,比如说每秒40000个连接,是完全承受不住的,响应速度会变得非常慢
另外一个弊端就是,在多线程应用中,所有的线程一般都通过如下的循环来接收来自客户端的连接
while (1) {
new_fd = accept(...);
process_connection(new_fd);
}
这种循环并不能很好地平衡每个线程的负载,很可能会出现一个线程忙得不得了,而另一个线程闲着没事干的情况
相比之下,端口复用使得每个线程都能均衡的收到连接
值得注意的一点是,连接的分配是由一个四元组确定的,即clientIP、clientPort、serverIP、serverPort
这样一来,同一对clientIP、clientPort只会被分发给同一个线程,这样有助于维护会话