How to get the device IP with flutter - linux

I am looking for a way to get the device IP that is not based on Wifi. I am unable to find the local IP of the current device when compiling to Linux app running on an ethernet connection with no wifi card.
I tried using 'package:wifi/wifi.dart' and 'package:network_info_plus/network_info_plus.dart' to get the device's local ip and both packages gave this error: MissingPluginException (MissingPluginException(No implementation found for method ip on channel plugins.ly.com/wifi))
Is there a way to get the device local IP without a Wifi card?
UPDATE:
Using https://stackoverflow.com/a/52411510/5861729 and https://stackoverflow.com/a/43803986/16477035 I was able to figure out a clean way to get my local ip.
// Find localIp
String localIp = '';
final List<String> privateNetworkMasks = ['10', '172.16', '192.168'];
for (var interface in await NetworkInterface.list()) {
for (var addr in interface.addresses) {
for (final possibleMask in privateNetworkMasks) {
if (addr.address.startsWith(possibleMask)) {
localIp = addr.address;
break;
}
}
}
}

Run 'flutter clean' then 'flutter pub get' and re install your app

Related

Cloud Run Service not picking up client correct IP address

I have a service hosted on Google Cloud Run. The service uses socket io whenever the service is up and running.
When a socket client connects to the service I have the following function that gets the ip address of the connected client from the socket as shown below and then I am hitting this GeoPlugin Link with the retrieved IP
async getSocketIP(socket) {
let { headers, address } = socket.handshake;
let { origin } = headers;
let ip = headers['x-forwarded-for'];
let userAgent = headers['user-agent'];
try {
let locationPointUrl = `http://www.geoplugin.net/json.gp?ip=${ip}`;
let { data: location } = await axios.get(locationPointUrl);
} catch (e) {
console.log(`Error get client online IP on Socket IO`);
}
}
Unfortunately, irrespective of the User's Location the IP always resolves to US.
I have a custom domain mapped to the cloud run service via Domain Mapping.
What could be the reason the IP of the Client is always US IP?
Please note that this same service when hosted on Heroku gets the correct IP address of the connected client.
So, I'm very certain that it has something to do with Cloud Run.
All my services on Cloud Run are on US-CENTRAL1
For anyone who may experience something like this in the future.
We had Cloudflare sitting in front of Cloud Run.
So, to get the correct Client's IP address all we had to do was retrieve it from cf-connecting-ip header instead of x-forwarded-for.
So, the modified and working code now becomes:
async getSocketIP(socket) {
let { headers, address } = socket.handshake;
let { origin } = headers;
let ip = headers['cf-connecting-ip'] ?? headers['x-forwarded-for']; //Notice the difference
let userAgent = headers['user-agent'];
try {
let locationPointUrl = `http://www.geoplugin.net/json.gp?ip=${ip}`;
let { data: location } = await axios.get(locationPointUrl);
} catch (e) {
console.log(`Error get client online IP on Socket IO`);
}
}

Device can't resolve host

I have simple DNS resolve demo in my ESP8266. Can't find why it cat resolve Ubuntu virtual machine on AWS. According to my understanding DNS server is my home router 192.168.1.1. Resolution works fine from my desktop PC while ESP8266 fails. Why and how to fix that?
void printDNSServers() {
Serial.print("DNS #1, #2 IP: ");
WiFi.dnsIP().printTo(Serial);
Serial.print(", ");
WiFi.dnsIP(1).printTo(Serial);
Serial.println();
}
void printIPAddressOfHost(const char* host) {
IPAddress resolvedIP;
if (!WiFi.hostByName(host, resolvedIP)) {
DEBUG_LOG("DNS lookup failed. ");
DEBUG_LOGLN(host);
}
DEBUG_LOGLN(host);
DEBUG_LOGLN(" IP: ");
Serial.println(resolvedIP);
}
void loop()
{
printDNSServers();
printIPAddressOfHost("yahoo.com");
printIPAddressOfHost("ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port");
}
Output is:
DNS #1, #2 IP: 192.168.1.1, (IP unset)
yahoo.com
IP:
98.138.219.232
DNS lookup failed. ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port
ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port
IP:
You are trying to resolve the following hostname:
ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port
You need to take the port off the end, as the current string is not a valid hostname.
ec2-34-254-225-201.eu-west-1.compute.amazonaws.com

Correct usage of AddressResolver interface

I was wondering if there is an example usage of the AddressResolver interface in apache ignite.
I was trying to 'bind' my local IP addresses (e.g. 192.168.10.101) to my external IP address using the AddressResolver interface, but without luck.
When I do that the Ignite server just hangs (no output from the debug either)
My code for starting the server is:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
ipFinder.setAddresses(ipaddresses);
spi.setIpFinder(ipFinder);
spi.setAddressResolver(new IotAddressResolver());
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
System.setProperty("IGNITE_QUIET", "false");
// Start Ignite node.
ignite = Ignition.start(cfg);
My implementation for AddressResolver is:
public class IotAddressResolver implements AddressResolver {
#Override
public Collection<InetSocketAddress> getExternalAddresses(
InetSocketAddress internalAddresses) throws IgniteCheckedException {
String host = "XX.XX.XX.XX";
Collection<InetSocketAddress> result = new ArrayList<InetSocketAddress>();
result.add(new InetSocketAddress(host, internalAddresses.getPort()));
return result;
}
}
The last line of the ignite debug log is:
WARNING: Timed out waiting for message to be read (most probably, the reason is in long GC pauses on remote node) [curTimeout=9989]
I will appreciate any help. Thank you
Can you provide more details about your deployment and what you're trying to achieve with the help of address resolver? How many physical hosts and Ignite nodes do you have? Are they located in different networks with the router between them?
I dont know if this is the best way to handle this but I managed to start igntie as local server. I am setting my local ip and port like this:
System.setProperty("IGNITE_QUIET", "false");
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
TcpCommunicationSpi commSpi = new TcpCommunicationSpi();
// Set initial IP addresses.
ipFinder.setAddresses(ipaddresses);
spi.setIpFinder(ipFinder);
// Override local port.
commSpi.setLocalPort(47501);
commSpi.setLocalAddress("XX.XX.XX.XX");
commSpi.setLocalPortRange(50);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default communication SPI.
cfg.setCommunicationSpi(commSpi);
cfg.setDiscoverySpi(spi);
cfg.setAddressResolver(new IotAddressResolver());
cfg.setClientMode(true);
// Start Ignite node
ignite = Ignition.start(cfg);
Where XX.XX.XX.XX is my local IP address

How to get IP of the client?

I've wrote a self-hosted servicestack server and a client, both desktop applications.
In my very basic PING test service I'm trying to retrieve the IP of the client.
Server is on 192.168.0.87:82, client I tried on the same computer and on another computer, but RemoteIp and UserHostAddress always return 192.168.0.87:82. XRealIp is null.
I also tried base.Request.RemoteIp, but still is 192.168.0.87:82.
What am I doing wrong?
public RespPing Any(ReqPing request)
{
string IP = base.RequestContext.Get<IHttpRequest>().RemoteIp;
string MAC = request.iTransactionInfo.MAC;
Log(MAC,IP, base.RequestContext.Get<IHttpRequest>().RemoteIp + base.RequestContext.Get<IHttpRequest>().XRealIp + base.RequestContext.Get<IHttpRequest>().UserHostAddress);
RespPing response = new RespPing { Result = "PONG" };
return response;
}
Thanks!
Made it with:
HttpListenerRequest iHttpListenerRequest = (HttpListenerRequest)base.RequestContext.Get<IHttpRequest>().OriginalRequest;
string IP = iHttpListenerRequest.RemoteEndPoint.ToString().Split(':')[0];
Request.RemoteIP kept giving me the server address.
ServiceStack.4.0.38
string IP = base.Request.RemoteIp;
fwiw I had to do something just a little bit different:
HttpListenerRequest iHttpListenerRequest = (HttpListenerRequest)base.RequestContext.Get<IHttpRequest>().OriginalRequest;
string ip = iHttpListenerRequest.RemoteEndPoint.Address.ToString();

How to broadcast Video using UDPCLient Class in C# over internet?

I am trying to develop a Video Client/functionality that captures video using webcam and transfers to other servent (server-client) somewhere on the internet. I am using UDPCLient Class to do that.
I want my application to be able to listen and tarnsmit video captured from webcam. The capturing, transmission and receiving works fine when i do that on local network.
But when i test the application from behind router (across two differnt networks/internet) after forwarding respective ports, the internet connectivity is lost on both routers (They hang up or something) and i need to restart the routers or switch to an alternate connection. The configuration is as follows:
Servent 1 <--> Router1 <--> Internet Connection#01
Servent 02 <---> Router2 <---> Internet Connection#02
Both connections are on separate DSL Line. One of the routers is ZTE brand and the other is of Netgear.
Code for listenning/transmission is as follows:
private void StartSockets()
{
//For testing across internet i use IPAddress obtained via different function
var IPAddress = getMyIpAddress();
this.udpSender = new UdpClient(IpAddress, 4000);
this.udpListener = new UdpClient(4000);
}
private IPAddress getMyIpAddress()
{
IPAddress localIP ;//= AddressAr[0];
localIP = IPAddress.Parse(GetPublicIP());
return localIP;
}
public string GetPublicIP()
{
String direction = "";
WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
using (WebResponse response = request.GetResponse())
{
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
direction = stream.ReadToEnd();
}
}
//Search for the ip in the html
int first = direction.IndexOf("Address: ") + 9;
int last = direction.LastIndexOf("</body>");
direction = direction.Substring(first, last - first);
return direction;
}
Code for receiving response is as follows:
private void ReceiveData()
{
//For testing across internet i use IPAddress obtained via different function
var IPAddress = getMyIpAddress();
IPEndPoint ep = new IPEndPoint(IPAddress, myPort);
try
{
byte[] receiveBytes = this.udpListener.Receive(ref ep);
this.OnReadImage(new ImageEventArgs(this.ByteToImage(receiveBytes)));
}
catch (Exception)
{
}
}
If i test on local network , i use DNSHostname to get ip address (private ip addresses) and video works fine on local network. That does not work over internet so i switch to live Ip Address and thus i use the method of getPublicIpAddress().
I know there is something seriously wrong with my approach? What would be right approach?
Should i switch to TCP Listenner? I intend to have multiple receiver of same video in future. So would that affect?
Can UDP clients cause routers to crash, hang up and restart? How can i avoid that?
Lastly, if were to avoid port-forwarding what would be the best strategy?
Please help.
Thanks
Steve

Resources