Linux 如何处理使用“INADDR_ANY”和特定 IP 地址绑定到同一端口的多个套接字?

问题描述 投票:0回答:1

我正在 Linux 上开发服务器应用程序,并且对使用

INADDR_ANY
和特定 IP 地址时的套接字绑定行为有疑问。我的设置涉及两个套接字:

  1. 一个套接字通过
    INADDR_ANY
    绑定到端口 80,这意味着它侦听所有可用的 IP 地址。
  2. 另一个套接字绑定到特定 IP 地址上的端口 80,
    66.117.236.114

我的问题是:

  1. 如果客户端尝试连接到端口 80 上的

    66.117.236.114
    ,是否有可能由绑定到
    INADDR_ANY
    的套接字而不是显式绑定到
    66.117.236.114
    的套接字处理该连接?

  2. 我还在两个插座上使用

    SO_REUSEADDR
    插座选项。这是否会影响连接的路由方式,或者纯粹与允许两个套接字绑定到同一端口而不会出现错误有关?

这是我如何绑定套接字的相关片段:

int sock1 = socket(AF_INET, SOCK_STREAM, 0);
int sock2 = socket(AF_INET, SOCK_STREAM, 0);

int optval = 1;
setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
setsockopt(sock2, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

// Socket 1: Bind to INADDR_ANY (all interfaces)
struct sockaddr_in addr1;
addr1.sin_family = AF_INET;
addr1.sin_addr.s_addr = htonl(INADDR_ANY);
addr1.sin_port = htons(80);
bind(sock1, (struct sockaddr*)&addr1, sizeof(addr1));

// Socket 2: Bind to specific IP address
struct sockaddr_in addr2;
addr2.sin_family = AF_INET;
addr2.sin_addr.s_addr = inet_addr("66.117.236.114");
addr2.sin_port = htons(80);
bind(sock2, (struct sockaddr*)&addr2, sizeof(addr2));

到目前为止我学到了什么:

  • 绑定到
    INADDR_ANY
    的套接字侦听所有可用的 IP,而另一个套接字仅侦听
    66.117.236.114
  • SO_REUSEADDR
    选项允许两个套接字绑定到同一端口而不会出现错误,但据我了解,它不控制哪个套接字处理传入连接。

我的关键问题:

  1. 是否有任何场景可以通过
    66.117.236.114:80
    套接字处理针对
    INADDR_ANY
    的连接?
  2. SO_REUSEADDR
    在这里扮演什么角色?
    它会影响哪个套接字处理传入连接,还是仅在绑定过程中相关?

期望的行为:

我想确保任何针对

66.117.236.114:80
的连接始终由第二个套接字(显式绑定到该地址的套接字)处理,并且与其他 IP(例如,
127.0.0.1:80
)的连接由
INADDR_ANY
套接字处理。

任何有关 Linux 如何处理此问题的澄清或确认将不胜感激!

c linux sockets tcp
1个回答
0
投票

上面的代码绑定了套接字,但您还没有尝试侦听任一套接字。 如果您尝试这样做:

rval = listen(sock1, 5);
if (rval==-1) {
    perror("listen failed for sock1");
    exit(1);
}
rval = listen(sock2, 5);
if (rval==-1) {
    perror("listen failed for sock2");
    exit(1);
}

其中一个会失败:

listen failed for sock2: Address already in use
© www.soinside.com 2019 - 2024. All rights reserved.