title: Socket.Bind and Connect using local addresses
body: <p>To test my server/client application, where each client is known by its IP address, I created several network adapters (see <a href="https://stackoverflow.com/questions/2234102/how-to-create-a-virtual-network-adapter-in-net">How to Create a Virtual Network Adapter in .NET?</a>). Both 192.168.0.10 and 11 now correspond to local ethernet adaptors (10 being the "real" one, 11 being a loopback adapter).</p>
  
  <p>The client can <code>Connect</code> itself to the server as long as it doesn't <code>Bind</code> its socket to a specific address. But if it does, the server doesn't notice anything and a timeout occurs in the client (I want to use <code>Bind</code> as for security reasons the server automatically detects which client is connecting itself by looking at the IP address of the remote end point of the new connection: the server will drop the connection at once if it doesn't know the IP address - previously I was using several virtual machines, but it uses a lot more RAM and is less practical to use).</p>
  
  <p>Here's the code in my server, listening eg on 192.168.0.10:1234</p>
  
  <pre><code>IPEndPoint myEP = new IPEndPoint(myAddress, myPort);
  Socket listeningSocket = new Socket(myAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  listeningSocket.Bind(myEP);
  listeningSocket.Listen(50);
  Socket acceptedSocket = listeningSocket.Accept();
  </code></pre>
  
  <p>Here's the code in my client, binding eg to 192.168.0.11 (any port) and connecting to 192.168.0.10:1234</p>
  
  <pre><code>Socket socket = new Socket(svrAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  socket.Bind(new IPEndPoint(myAddress, 0)); // Bind to local address using automatic port
  socket.Connect(new IPEndPoint(svrAddress, svrPort)); // Works fine without Bind, timeout with Bind
  </code></pre>
  
  <p>I've tried the same using the corresponding IPv6 addresses but I get the exact same result.
  If I <code>Bind</code> the client on the same address (using a different port than the server), it works fine.</p>
  
  <p>Any idea what I'm doing wrong? </p>
  
  <p>EDIT Here is my test projects (it might be useful to someone)</p>
  
  <p>Server part:</p>
  
  <pre><code>using System;
  using System.Net;
  using System.Net.Sockets;
  using System.Threading.Tasks;
  
  namespace Server
  {
      class Program
      {
          static void Main(string[] args)
          {
              IPAddress[] ips = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
  
              string line = string.Empty;
              while (line != "q")
              {
                  // Gets the IP address to listen on.
                  Console.WriteLine("IP to listen on:");
                  int count = 0;
                  foreach (IPAddress ip in ips)
                      Console.WriteLine("{0}: {1}", ++count, ip.ToString());
  
                  string numString = Console.ReadLine();
                  int pos = Convert.ToInt32(numString) - 1;
                  IPAddress myAddress = ips[pos]; // Removing or not the scope ID doesn't change anything as "localEndPoint" below will contain it no matter what
  
                  // Binds and starts listening.
                  IPEndPoint myEP = new IPEndPoint(myAddress, 12345);
                  Socket listeningSocket = new Socket(myAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                  listeningSocket.Bind(myEP);
                  listeningSocket.Listen(50);
  
                  IPEndPoint localEndPoint = (IPEndPoint)listeningSocket.LocalEndPoint;
                  Console.WriteLine("Listening on {0}:{1}", localEndPoint.Address, localEndPoint.Port);
  
                  Task.Factory.StartNew(() =&gt;
                      {
                          try
                          {
                              // Accepts new connections and sends some dummy byte array, then closes the socket.
                              Socket acceptedSocket = listeningSocket.Accept();
                              IPEndPoint remoteEndPoint = (IPEndPoint)acceptedSocket.RemoteEndPoint;
                              Console.WriteLine("Accepted connection from {0}:{1}.", remoteEndPoint.Address, remoteEndPoint.Port);
                              acceptedSocket.Send(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                              acceptedSocket.Close(5000);
                              Console.WriteLine("-= FINISHED =- Type q to quit, anything else to continue");
                          }
                          catch (Exception ex)
                          { }
                      });
  
                  line = Console.ReadLine();
  
                  // Closes the listening socket.
                  listeningSocket.Close();
              }
          }
      }
  }
  </code></pre>
  
  <p>Client part</p>
  
  <pre><code>using System;
  using System.Linq;
  using System.Net;
  using System.Net.Sockets;
  using System.Threading.Tasks;
  
  namespace Client
  {
      class Program
      {
          static void Main(string[] args)
          {
              IPAddress[] ips = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
  
              string line = string.Empty;
              while (line != "q")
              {
                  // Gets the IP address to connect to (removes the "scope ID" if it's an IPv6).
                  Console.WriteLine("IP to connect to:");
                  int count = 0;
                  foreach (IPAddress ip in ips)
                      Console.WriteLine("{0}: {1}", ++count, ip.ToString());
  
                  string numString = Console.ReadLine();
                  int pos = Convert.ToInt32(numString) - 1;
                  IPAddress svrAddress = ips[pos].AddressFamily == AddressFamily.InterNetworkV6
                      ? new IPAddress(ips[pos].GetAddressBytes())
                      : ips[pos];
  
                  Console.WriteLine("Connecting to " + svrAddress);
  
                  // Gets the IP address to bind on (can chose "none" - also removes the "scope ID" if it's an IPv6).
                  Console.WriteLine("IP to bind to:");
                  Console.WriteLine("0: none");
                  count = 0;
                  IPAddress[] filteredIps = ips.Where(i =&gt; i.AddressFamily == svrAddress.AddressFamily).ToArray();
                  foreach (IPAddress ip in filteredIps)
                      Console.WriteLine("{0}: {1}", ++count, ip.ToString());
  
                  numString = Console.ReadLine();
                  pos = Convert.ToInt32(numString) - 1;
                  IPEndPoint localEndPoint = (pos == -1)
                      ? null
                      : new IPEndPoint(
                          filteredIps[pos].AddressFamily == AddressFamily.InterNetworkV6
                              ? new IPAddress(filteredIps[pos].GetAddressBytes())
                              : filteredIps[pos]
                          , 0);
                  Console.WriteLine("Binding to " + (localEndPoint == null ? "none" : localEndPoint.Address.ToString()));
  
                  // Binds to an address if we chose to.
                  Socket socket = new Socket(svrAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                  if (localEndPoint != null)
                      socket.Bind(localEndPoint);
  
                  Task.Factory.StartNew(() =&gt;
                  {
                      try
                      {
                          // Connects to the server and receives the dummy byte array, then closes the socket.
                          socket.Connect(new IPEndPoint(svrAddress, 12345));
                          IPEndPoint remoteEndPoint = (IPEndPoint)socket.RemoteEndPoint;
                          Console.WriteLine("Connected to {0}:{1}", remoteEndPoint.Address, remoteEndPoint.Port);
                          byte[] buffer = new byte[10];
                          Console.WriteLine((socket.Receive(buffer) == buffer.Length) ? "Received message" : "Incorrect message");
                          socket.Close();
                      }
                      catch (Exception ex)
                      {
                          // An exception occured: should be a SocketException due to a timeout if we chose to bind to an address.
                          Console.WriteLine("ERROR: " + ex.ToString());
                      }
                      Console.WriteLine("-= FINISHED =- Type q to quit, anything else to continue");
                  });
  
                  line = Console.ReadLine();
              }
          }
      }
  }
  </code></pre>