多网卡 socket 的bind问题

delphi中请问,在多网卡中socket的bind (ip地址采用 sin_addr.S_un.S_addr=INADDR_ANY)是那块网卡的ip

1楼:最简单方法,同时运行另外一个程序,bind一个地址,如果成功,则不是这个地址,否则。。。
2楼:接收本机所有网络接口的数据,如果绑定则接收绑定接口的数据
3楼:我是说绑定特定IP则会接收那个接口的数据
7楼:If an application does not care what local address is assigned, specify the manifest constant value ADDR_ANY for the sa_data member of the name parameter. This allows the underlying service provider to use any appropriate network address, potentially simplifying application programming in the presence of multihomed hosts (that is, hosts that have more than one network interface and address).
抄自MSDN,按这样说,是不是意味着我们用ADDR_ANY的时候就不会去关心到底bind了哪一块网卡,如果你比较关心这一点,不如直接去bind某一块,而不会使用ADDR_ANY.
8楼:INADDR_ANY是所有网卡的地址
9楼:是由底层操作系统选择的任何一块可用的网卡

发表于:2005-12-11 20:39:09

如果在建立socket的时候sin_addr .s_addr = INADDR_ANY;
这样的话网卡邦定是随机邦定的吗?在有多网卡的机器中
有这样一个问题,比如我有两个网卡 ip分别为128.128.1.14 和128.128.2.15 子网掩码分别是255.255.255.0和255.255.0.0,如果我这时候用INADDR_ANY参数向128.128.1.255发送数据,这是一个广播包(从1.14网卡发送)还是一个单播包(从2.15网卡发送)?,我试验了几十次用ethreal抓包,发现有一次被当作了单播包,其他都当成了广播包从1.14的网卡发送出去了,但是后来一直都没办法重现,都被当成广播的了,我不知道是我自己那次试验弄错了还是怎么样 特向大家请教,在多网卡环境的邦定过程

Windows网络编程总结(一)
作者: Kendiv
出处: CSDN.NET
  关于bind:
  INADDR_ANY 的具体含义是,绑定到0.0.0.0。此时,对所有的地址都将是有效的,如果系统考虑冗余,采用多个网卡的话,那么使用此种bind,将在所有网卡上进行绑定。在这种情况下,你可以收到发送到所有有效地址上数据包。
  例如:
  SOCKADDR_IN Local;
  Local.sin_addr.s_addr = htonl(INADDR_ANY);   
  另外一种方式如下:
  SOCKADDR_IN Local;
  hostent* thisHost = gethostbyname( " ");
  char* ip = inet_ntoa(*(struct in_addr *)*thisHost-> h_addr_list);
  Local.sin_addr.s_addr = inet_addr(ip);
  在这种方式下,将在系统中当前第一个可用地址上进行绑定。在多网卡的环境下,可能会出问题。 
  最常见的方式:
  const char LocalIP[] = "192.168.0.100 ";

  SOCKADDR_IN Local;
  Local.sin_addr.s_addr = inet_addr(LocalIP);
  bind(socket, (LPSOCKADDR)&Local, sizeof(SOCKADDR_IN)
  bind的安全问题:
  如果你在bind时,使用了INADDR_ANY那么,你将可以在所有有效的地址上进行监听,但是Socket有一个特性:可在同一端口上绑定多个Socket。

  让我们看看下面的情况:假设你的系统只有一个IP:192.168.0.100,你希望bind到4096端口。对于下面的两种bind,当数据包到达时,谁会接收到呢?
  Local.sin_addr.s_addr = htonl(INADDR_ANY);
  Local.sin_addr.s_addr = inet_addr(“192.168.0.100”);
  WinSocke库是这样处理的:谁绑定的最明确,谁获取数据包。显然,第二种bind将获取到达的数据包。如果避免这种情况呢?使用SO_EXECLUSINEADDRUSE选项。需要注意的是,此选项在Windows NT 4 Service Pack 4以后(包括SP4)才可以使用。
  示例代码:
  #ifndef SO_EXECLUSINEADDRUSE
  #define SO_EXECLUSINEADDRUSE ((int)(~SO_REUSEADDR))
  #endif
  SOCKADDR_IN Local;
  BOOL val = TRUE;   
  Local. sin_family = AF_INET;
  Local. sin_port = htons(4096);
  Local.sin_addr.s_addr = htonl(INADDR_ANY);   
  setsocketopt(socket, SOL_SOCKET, SO_EXECLUSINEADDRUSE, (char*)&val, sizeof(val));   
  bind(socket, (LPSOCKADDR)&Local, sizeof(SOCKADDR_IN)

如果需要使用特定的本地终结点,请使用 Bind 方法。必须先调用 Bind,然后才能调用 Listen 方法。除非需要使用特定的本地终结点,否则不必在使用 Connect 方法之前调用 Bind。对无连接和面向连接的协议都可以使用 Bind 方法。

在调用 Bind 之前,必须首先创建打算从其进行数据通信的本地 IPEndPoint。如果您不介意分配哪个本地地址,则可以用 IPAddress.Any 作为地址参数创建一个 IPEndPoint,这样,基础服务提供程序将会分配最适合的网络地址。如果您有多个网络接口,这将有助于简化您的应用程序。如果您不介意使用哪个本地端口,则可以创建一个使用 0 作为端口号的 IPEndPoint。在这种情况下,服务提供程序将会分配一个可用的端口号(介于 1024 和 5000 之间)。

如果使用上面的方法,您可以通过调用 LocalEndPoint 获知所分配的本地网络地址和端口号。如果当前使用的是面向连接的协议,则直到您调用了 Connect EndConnect 方法后,LocalEndPoint 才会返回本地分配的网络地址。如果当前使用的是无连接协议,则直到完成一个发送或接收操作后,才可访问该信息。

 

如果打算接收多路广播的数据报,则必须使用多路广播端口号调用 Bind 方法。

 

如果打算通过使用 ReceiveFrom 方法来接收无连接的数据报,则必须调用 Bind 方法。

 

如果在调用 Bind 方法时接收到 SocketException,则可以使用 SocketException.ErrorCode 属性获取特定的错误代码。获取此代码后,您可以参考 MSDN Library 中的 Windows Sockets 第 2 版 API 错误代码文档,获取有关该错误的详细说明。

 

当在应用程序中启用网络跟踪功能后,此成员将输出跟踪信息。有关更多信息,请参见 网络跟踪

<think>好的,我现在需要帮助用户理解socket编程中bind函数的用法,并提供示例和说明。首先,我得回顾一下bind函数的作用和相关知识。根据用户提供的引用资料,bind函数用于将套接字绑定到特定的地址和端口,这在服务端设置中尤其重要,因为它指定了套接字监听的网络接口和端口号。 首先,我需要确认bind函数的函数原型。引用[1]和[4]提到函数声明是int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);。参数包括套接字描述符sockfd,指向sockaddr结构体的指针addr,以及地址长度addrlen。addr参数可能根据协议族的不同而变化,比如IPv4使用sockaddr_in,IPv6使用sockaddr_in6,或者本地套接字使用sockaddr_un。 接下来,用户需要示例代码。根据引用[2],Python中使用socket.socket创建套接字,并调用bind方法。而C语言的示例可能需要更详细的步骤,包括填充sockaddr_in结构体,设置地址族、端口和IP地址,然后调用bind函数。这里需要注意网络字节序转换,使用htons函数转换端口号,inet_addr转换IP地址。 另外,引用[3]提到Qt中的QUdpSocket类也有bind方法,但用户的问题可能更多集中在传统的C或Python实现上。所以示例应该包括Python和C两种语言的代码,以满足不同用户的需求。 在解释步骤时,需要分点说明,例如创建套接字、准备地址结构体、调用bind函数以及错误处理。同时,需要强调bind函数在服务端的作用,客户端通常不需要调用bind,除非需要指定特定的端口或IP。 还要注意常见错误,比如端口被占用(EADDRINUSE),权限不足(EACCES)等,应该在示例中加入错误检查和处理,比如在C中使用perror输出错误信息,Python中捕获异常。 最后,根据用户提供的引用[4]和[5],可能需要提到bind之后的其他步骤,比如listen和accept,但用户主要关注bind,所以示例可能不需要完整代码,但给出上下文会有帮助。例如,在服务端代码中,bind之后通常会有listen和accept。 总结一下,回答的结构应该是:函数原型说明,参数解释,步骤说明,示例代码(Python和C),常见问题及注意事项。同时,生成的相关问题需要围绕bind函数的使用场景、参数细节、错误处理等展开,帮助用户进一步学习。</think>### socketbind函数的用法详解 #### 1. 函数作用 `bind()`函数将套接字与特定的**IP地址+端口号**绑定,使套接字能够监听指定网络接口的请求。服务端程序必须调用此函数建立通信端点[^1][^4]。 #### 2. 函数原型 ```c #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); ``` - `sockfd`: socket()创建的套接字描述符 - `addr`: 指向地址结构体的指针(需强制转换类型) - `addrlen`: 地址结构体的大小 #### 3. 核心步骤(以IPv4为例) 1. **创建套接字**: ```c int sockfd = socket(AF_INET, SOCK_STREAM, 0); ``` 2. **配置地址结构**: ```c struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; // 协议族 serv_addr.sin_port = htons(8080); // 端口号(需网络字节序) serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 接受任意网卡请求 ``` 3. **执行绑定**: ```c if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) { perror("Bind failed"); exit(EXIT_FAILURE); } ``` #### 4. 示例代码(Python) ```python import socket serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serv.bind(('0.0.0.0', 8080)) # 绑定所有网卡的8080端口[^2] ``` #### 5. 关键参数说明 - `INADDR_ANY`:允许接收所有网络接口的数据包 - 端口范围:1-1024为系统保留端口,需root权限 - 地址重用:通过`setsockopt()`设置`SO_REUSEADDR`可解决`EADDRINUSE`错误 #### 6. 典型应用场景 | 场景 | 配置要点 | |-----------|--------------------------| | 服务端程序 | 必须显式绑定端口 | | UDP接收端 | 绑定后可用`recvfrom()`接收数据[^3] | | 客户端程序 | 通常无需手动绑定,由系统自动分配端口 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值