简体   繁体   中英

How does a client communicate with a Windows Service on a machine with multiple adapters?

I've inherited a Windows Service + Client application written in C#. The Windows Service opens a TCP/IP socket for listening as follows:

socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPHostEntry iphe = Dns.Resolve(Dns.GetHostName());
socket.Bind(new IPEndPoint(iphe.AddressList[0], ExportServiceRequest.DefaultPort));
socket.Listen(2);
// Wait for incoming connections and Accept them.

while the client connects as follows:

using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
    IPHostEntry iphe = Dns.Resolve(Dns.GetHostName());
    IPEndPoint ep = new IPEndPoint(iphe.AddressList[0], ExportServiceRequest.DefaultPort);
    socket.Connect(ep);
    // Talk to the server
}

The problem is that on certain machines with multiple network adapters, the 'wrong' adapter is picked by Dns.Resolve(), and the client connection fails.

I am aware that this code is aged and reeking, and haven't coded much raw socket code. Is there a best way to implement a Windows Service listening on a socket, such that at least local connections (from within the same machine) always succeed, regardless of how many network adapters the machine has?

Edit: my question appears poorly formulated. At the end of the day, I want the Windows Service to be accessible by a client, which always is running on the same machine, with no need for configuration. To anthropomorphize, I want the Windows Client to just yell at the server, "what IP address can I talk to you, oh Service running on TCP port ExportServiceRequest.DefaultPort on $LOCALHOST$? I want to talk to you", and have the ensuing TCP/IP conversation just work.

Socket.Bind :

Before calling Bind , you must first create the local IPEndPoint from which you intend to communicate data. If you do not care which local address is assigned, you can create an IPEndPoint using IPAddress.Any as the address parameter, and the underlying service provider will assign the most appropriate network address. This might help simplify your application if you have multiple network interfaces.

(emphasis added). So that would be one suggested change.

I'd also suggest switching your Connect call to Connect(string,int) :

Establishes a connection to a remote host. The host is specified by a host name and a port number.

(a host value of 'localhost' should be sufficient there)

That is, get rid of all of this mucking about with DNS, etc, and just rely on the underlying infrastructure to resolve these issues.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM