English 中文(简体)
利用专门的网络接口处理窗户的袖珍
原标题:Using a specific network interface for a socket in windows

视窗是否除了改变路径表外,还能可靠地迫使新创建的袖珍使用特定的网络接口? 我的理解是,连接IP地址的bind()并不能保证这一点。

最佳回答

(Ok第二次 l。)

FYI在此有另一个问题:

http://technet.microsoft.com/en-us/magazine/2007.09.cableguy.aspx” rel=“nofollow noreferer” The Cable Guy

Windows XP and Windows Server® 2003 use the weak host model for sends and receives for all IPv4 interfaces and the strong host model for sends and receives for all IPv6 interfaces. You cannot configure this behavior. The Next Generation TCP/IP stack in Windows Vista and Windows Server 2008 supports strong host sends and receives for both IPv4 and IPv6 by default on all interfaces except the Teredo tunneling interface for a Teredo host-specific relay.

因此,回答您在Windows XP和Windows 2003 IP4中提出的问题(适当的时候),但IP6 是。 Windowsista和Windows 2008 是(某些情况除外)。

另见https://forums.codeguru.com/showthread.php?487139-Socket- binding-with-routing-table

On Windows, a call to bind() affects card selection only incoming traffic, not outgoing traffic. Thus, on a client running in a multi-homed system (i.e., more than one interface card), it s the network stack that selects the card to use, and it makes its selection based solely on the destination IP, which in turn is based on the routing table. A call to bind() will not affect the choice of the card in any way.

It s got something to do with something called a "Weak End System" ("Weak E/S") model. Vista changed to a strong E/S model, so the issue might not arise under Vista. But all prior versions of Windows used the weak E/S model.

With a weak E/S model, it s the routing table that decides which card is used for outgoing traffic in a multihomed system.

See if these threads offer some insight:

"Local socket binding on multihomed host in Windows XP does not work" at http://www.codeguru.com/forum/showthread.php?t=452337

"How to connect a port to a specified Networkcard?" at http://www.codeguru.com/forum/showthread.php?t=451117. This thread mentions the CreateIpForwardEntry() function, which (I think) can be used to create an entry in the routing table so that all outgoing IP traffic with a specified server is routed via a specified adapter.

"Working with 2 Ethernet cards" at http://www.codeguru.com/forum/showthread.php?t=448863

"Strange bind behavior on multihomed system" at http://www.codeguru.com/forum/showthread.php?t=452368

希望帮助!

问题回答

我不敢肯定,为什么你说约束不可靠地工作。 赠款 我没有做详尽的测试,但以下解决办法对我来说是可行的(Win10, 视觉演播室,2019年)。 我需要通过某个特定的通信通信公司发出广播信息,因为计算机上可能会有多个通信通信公司。 在下表中,我希望广播信息能够与IP公司联系。

概述:

  • create a socket
  • create a sockaddr_in address with the IP address of the NIC you want to send FROM
  • bind the socket to that FROM sockaddr_in
  • create another sockaddr_in with the IP of your broadcast address (255.255.255.255)
  • do a sendto, passing the socket created is step 1, and the sockaddr of the broadcast address.

............

static WSADATA     wsaData;

static int ServoSendPort = 8888;
static char ServoSendNetwork[] = "192.168.202.106";
static char ServoSendBroadcast[] = "192.168.255.255";

............ ...... < snip >

if ( WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR )
      return false;


// Make a UDP socket
SOCKET ServoSendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
int iOptVal = TRUE;
int iOptLen = sizeof(int);
int RetVal = setsockopt(ServoSendSocket, SOL_SOCKET, SO_BROADCAST, (char*)&iOptVal, iOptLen);
              
// Bind it to a particular interface
sockaddr_in ServoBindAddr={0};
ServoBindAddr.sin_family = AF_INET;
ServoBindAddr.sin_addr.s_addr = inet_addr( ServoSendNetwork ); // target NIC
ServoBindAddr.sin_port = htons( ServoSendPort );
int bindRetVal = bind( ServoSendSocket, (sockaddr*) &ServoBindAddr, sizeof(ServoBindAddr) );
if (bindRetVal == SOCKET_ERROR )
{
    int ErrorCode = WSAGetLastError();
    CString errMsg;
    errMsg.Format (  _T("rats!  bind() didn t work!  Error code %d
"), ErrorCode );
    OutputDebugString( errMsg );
}


// now create the address to send to......
sockaddr_in ServoSendAddr={0};
ServoSendAddr.sin_family = AF_INET;
ServoSendAddr.sin_addr.s_addr = inet_addr( ServoSendBroadcast ); // 
ServoSendAddr.sin_port = htons( ServoSendPort );

......

#define NUM_BYTES_SERVO_SEND 20
unsigned char sendBuf[NUM_BYTES_SERVO_SEND];
int BufLen = NUM_BYTES_SERVO_SEND;

ServoSocketStatus = sendto(ServoSendSocket, (char*)sendBuf, BufLen, 0, (SOCKADDR *) &ServoSendAddr, sizeof(ServoSendAddr));
if(ServoSocketStatus == SOCKET_ERROR)
{
    ServoUdpSendBytes = WSAGetLastError();
    CString message;
    message.Format(_T("Error transmitting UDP message to Servo Controller: %d."), ServoSocketStatus);
    OutputDebugString(message);
    return false;
 }




相关问题
Why running a service as Local System is bad on windows?

I am trying to find out the difference between difference service account types. I tumbled upon this question. The answer was because it has powerful access to local resources, and Network Service ...

Programmatically detect Windows cluster configuration?

Does anyone know how to programatically detect that a Windows server is part of a cluster? Further, is it possible to detect that the server is the active or passive node? [Edit] And detect it from ...

get file icon for Outlook appointment (.msg)

I ve read Get File Icon used by Shell and the other similar posts - and already use SHFileInfo to get the associated icon for any given extension, and that works great. However, Outlook uses ".msg" ...

Identifying idle state on a windows machine

I know about the GetLastInputInfo method but that would only give me the duration since last user input - keyboard or mouse. If a user input was last received 10 minutes ago, that wouldn t mean the ...

Terminating a thread gracefully not using TerminateThread()

My application creates a thread and that runs in the background all the time. I can only terminate the thread manually, not from within the thread callback function. At the moment I am using ...

热门标签