public static IPAddress GetBestLocalIPAddress(String host, TNET_Socket.tnet_socket_type_t type) { try { #if WINDOWS_PHONE String localHostNameOrAddress = (host == TNET_Socket.TNET_SOCKET_HOST_ANY) ? "localhost" : host; // Not use yet IPAddress[] ipAddresses = new IPAddress[] { TNET_Socket.IsIPv6Type(type) ? IPAddress.IPv6Any : IPAddress.Any }; // FIXME: didn't found how to get local IP on WP7 #else String localHostNameOrAddress = (host == TNET_Socket.TNET_SOCKET_HOST_ANY) ? Dns.GetHostName() : host; IPAddress[] ipAddresses = Dns.GetHostAddresses(localHostNameOrAddress); #endif IPAddress ipAddress = null; Boolean useIPv6 = TNET_Socket.IsIPv6Type(type); if (ipAddresses != null && ipAddresses.Length > 0) { ipAddress = ipAddresses[0]; foreach (IPAddress ia in ipAddresses) { if ((ia.AddressFamily == AddressFamily.InterNetwork && (IPAddress.Loopback.ToString().Equals(ia.ToString()))) || (ia.AddressFamily == AddressFamily.InterNetworkV6 && (IPAddress.IPv6Loopback.ToString().Equals(ia.ToString())))) { continue; } if ((ia.AddressFamily == AddressFamily.InterNetwork && !useIPv6) || (ia.AddressFamily == AddressFamily.InterNetworkV6 && !ia.IsIPv6LinkLocal && useIPv6)) { ipAddress = ia; break; } } } if (ipAddress == null) { TSK_Debug.Error("{0} is an invalid hostname or address", localHostNameOrAddress); ipAddress = TNET_Socket.IsIPv6Type(type) ? IPAddress.IPv6Any : IPAddress.Any; } return(ipAddress); } catch (Exception e) { TSK_Debug.Error("GetBestLocalIPAddress(host={0}) failed: ", host, e); } return(TNET_Socket.IsIPv6Type(type) ? IPAddress.IPv6Any : IPAddress.Any); }
public TNET_Socket(String host, ushort port, tnet_socket_type_t type, Boolean nonblocking, Boolean bindsocket) { mId = ++sUniqueId; mType = type; mHost = host; mPort = port; mSocketEvent = new ManualResetEvent(false); mSendSocketEventArgs = new SocketAsyncEventArgs(); mSendSocketEventArgs.Completed += delegate(object sender, SocketAsyncEventArgs e) { if (e.SocketError != SocketError.Success) { mSocketEvent.Set(); return; } // On WP7 Socket.ReceiveFromAsync() will only works after at least ONE SendTo() if (e.LastOperation == SocketAsyncOperation.SendTo) { if (mRecvSocketEventArgs == null && RecvSocketCompleted != null) { mRecvSocketEventArgs = new SocketAsyncEventArgs(); // setting the remote endpoint will not filter on the remote host:port // => will continue to work even if the remote port is different than 5060 // IPEndPoint is not serializable => create new one mRecvSocketEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 5060); // e.RemoteEndPoint mRecvSocketEventArgs.Completed += this.RecvSocketCompleted; mRecvSocketEventArgs.SetBuffer(buffers, 0, buffers.Length); mRecvSocketEventArgs.UserToken = e.UserToken; (mRecvSocketEventArgs.UserToken as TNET_Socket).Socket.ReceiveFromAsync(mRecvSocketEventArgs); } } mSocketEvent.Set(); }; AddressFamily addressFamily = TNET_Socket.IsIPv6Type(type) ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork; SocketType socketType = TNET_Socket.IsStreamType(type) ? SocketType.Stream : SocketType.Dgram; #if WINDOWS_PHONE ProtocolType protocolType = TNET_Socket.IsStreamType(type) ? ProtocolType.Tcp : ProtocolType.Udp; #else ProtocolType protocolType = TNET_Socket.IsIPv6Type(type) ? ProtocolType.IP : ProtocolType.IP; // Leave it like this #endif mSocket = new Socket(addressFamily, socketType, protocolType); #if !WINDOWS_PHONE mSocket.Blocking = !nonblocking; mSocket.UseOnlyOverlappedIO = true; #endif mSendSocketEventArgs.UserToken = this; if (bindsocket) { IPAddress ipAddress = TNET_Utils.GetBestLocalIPAddress(host, type); TSK_Debug.Info("Local address={0}", ipAddress); mHost = ipAddress.ToString(); if (bindsocket) { ushort localPort = (port == TNET_SOCKET_PORT_ANY) ? (ushort)0 : port; IPEndPoint localIEP = new IPEndPoint(ipAddress, localPort); #if !WINDOWS_PHONE mSocket.Bind(localIEP); #endif if (TNET_Socket.IsDatagramType(type)) { #if !WINDOWS_PHONE mPort = (ushort)(mSocket.LocalEndPoint as IPEndPoint).Port; #endif } } } }