WinCE 6.0, work with GPRS/WiFi - c#

I'm working on a project, which should connect to servers through wifi/gprs. Project is an application for Windows CE 6.0 device, I'm writing in Visual Studio 2008 on C#.
I have two severs to work with. The first I have to connect via wifi, second - via gprs. So I need to know, how can I change the method of connecting between wifi and gprs?
I found and tried this way: I turn on both wifi and gprs on my device. So I work via wifi because it has a higher priority. When I need to work via gprs, I turn off wifi (SetDevicePower function). But when I turn wifi on, it doesn't connect back to my Preferred Network.
Also I heard about the way to change priority between gprs/wifi in OS priority table programmatically, but I didn't find any information about how to do this.
I hope you can help me.

I would use the route command from a shell.
lets assume
server1 ip: 123.123.123.1
server2 ip: 123.123.123.2
wifi ip : 192.168.1.101
gateway: 192.168.1.1
gprs ip : 10.1.2.3
gateway: 10.1.1.1
Now you can excute in a command prompt
route add 123.123.123.1 MASK 255.255.255.255 192.168.1.1
and
route add: 123.123.123.2 MASK 255.255.255.255 10.1.1.1
This should route all trafic to server 1 over wifi and to server 2 over gprs, without changing a single line of code in your app.
You can verify it worked with
tracert 123.123.123.1
tracert 123.123.123.2
However, you could use your app to periodically perform this task (I assume gprs ip could change from time to time) with Process.Start(...)
- delete route 1
- add route 1
- delete route 2
- add route 2
You even could specify the interface with the IF 2 switch (route list prints the interface id for your network cards).
Another interesting post to read is this one: http://ce4all.blogspot.com/2007/05/routing-ip-traffic-via-specified.html
The author uses the GetAdapterAddresses() and CreateIpForwardEntry() P/Invokes:
http://msdn.microsoft.com/en-us/library/ms927384.aspx
http://msdn.microsoft.com/en-us/library/ee495149%28v=winembedded.60%29.aspx

Related

How to check if server is reachable in PCL project xamarin?

I have been searching for solution to test or check the connectivity between my device and the server that contains my database.
Note: I want to implement the solution on my PCL project.
You can use James Montemagno's Connectivity Plugin for this.
You can either check if the device you are using is connected by calling;
bool isConnected = CrossConnectivity.Current.IsConnected;
Or, you can 'ping' a server to see if it can be reached. You can do that like this:
var isReachable = await CrossConnectivity.Current.IsReachable("google.com", 5000);
You can also provide an IP address. The second parameter is the timeout which defaults to 5 seconds. There is also the specific IsRemoteReachable method which also let's you specify a port number.
This library can be used in a PCL.
Note; for Android you will need the ACCESS_NETWORK_STATE and ACCESS_WIFI_STATE permissions, it should be added automatically when you install the NuGet package.
In the most cases it is completed with ICMP pings. You can ping the server every 1-5 secs depending on your appliation. But I suggest to use multicast address and ping that from the server because of performance and securtiy reasons (the last one needs firewall be configurated on server side too). You can determine connectivity lost if some of the replys (at least 3) doesn't reach the target host.

force WCF channel to ip address

I have two computers and they are connected via ethernet, i have set up an WCF connection and this all works ok, however when i host the same wcf on the local pc as the one i want to comunicate to and then do a wcf request via a channel, the request does not go to the remote pc but to my local pc. Is there a way to force a wcf request from a channel to go trough a specific ipaddress and not just go to any?
i'll try to explain how i use this:
there are two computers they are both similar and have two network adapters who have the same ipaddess and run thesame wcf software. so for example ipaddress for adapter 1 is: 10.10.10.1 and the other adapter is 10.10.10.2 on the same pc, and the other pc is similar. now these two pc need to communicate so i wire the two network adapters in cross example: pc 1 network adapter one goes to pc 2 network adapter 2. this so they are connected in 2 ways. so if i want to communicate with a simple socket from one to the other and back over the second adapter this all goes ok becouse i can bind a socket to a ipaddress and it will send it via the adapter it is bound to. but this does not seem to work with WCF. if i have two hosts on one pc, one for adapter 10.10.10.1 and one on 10.10.10.2 for the other adapter and i send a message to 10.10.10.2 that is on the remote pc, it will go in via the second network adapeter.
PC1 network adapter 1 (10.10.10.1) <--direct patch cable connection--> PC2 network adapter 2 (10.10.10.2)
PC1 network adapter 2 (10.10.10.2) <--direct patch cable connection--> PC2 network adapter 1 (10.10.10.1)
These connection arrows are direct connection patch cables!
all network adapters have a wcf hosted, and the software on both pc's is thesame.
this is all done for redundancy, more then two pc can be connected in a chain with this.
this is a little example of how i setup a request to the remote host:
public void Test()
{
string endPoint = "net.tcp://10.10.10.2:9985/connection";
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
binding.ListenBacklog = 2000;
binding.MaxConnections = 2000;
binding.TransferMode = TransferMode.Buffered;
binding.MaxReceivedMessageSize = 104857600;
binding.SendTimeout = new TimeSpan(0, 1, 0);
binding.CloseTimeout = new TimeSpan(0, 0, 1);
binding.OpenTimeout = new TimeSpan(0, 0, 1);
binding.ReceiveTimeout = new TimeSpan(0, 1, 0);
//binding.HostNameComparisonMode = HostNameComparisonMode.Exact;
//binding.PortSharingEnabled = false;
ChannelFactory<Connection> pipeFactory = new ChannelFactory<Connection>(binding, new EndpointAddress(endPoint));
var pipeProxy = this.ChannelFactory.CreateChannel();
//fictional method: pipeProxy.SendRequestTunnelTo("10.10.10.1"); //this is the ipaddress that it should go out to however it goes out to "10.10.10.2"
//and this is another network adapter also on the local mashine and here is also a wcf host on
((IClientChannel)pipeProxy).AllowOutputBatching = true;
((IClientChannel)pipeProxy).Open();
pipeProxy.SystemRequest(); //do function
}
Ok, the issue here is routing. If windows thinks it can deliver the traffic directly to the other IP Address, it will do so.
In this case, it can't differentiate between the local 10.10.10.2 that it knows about and one that's on another network hidden behind a NAT.
The preferred solution is to not use the same subnet (so have 10.10.10.2 and 10.11.10.2 or similar), however that can sometimes require significant changes.
The next best option is to use the IP address of the NAT and have it port forward.
Say you have a setup like this (where the boxes with 2 ip addresses are NATing routers with both public and internal IPs)...
10.10.10.2 --- [10.10.10.1 | 1.2.3.4] --- Internet --- [5.6.7.8 | 10.10.10.1] -- 10.10.10.2
Then the machine on the left should try to connect to 5.6.7.8 which should forward connections to the machine on the right (and vice-versa with the right machine connecting to 1.2.3.4).
If you've got a WAN setup that makes the machines appear to be in the same network, that's as much of a problem as being on the same network. None of the routers on the network will be able to determine which 10.10.10.2 you mean,
If you weren't using exactly the same IP address, you might be able to force the issue using routing tables on your windows box. This can allow you to specify preferential routes so that all traffic for a given IP address goes out over the specified NIC. Unfortunately, beyond that point it's out of your control and entirely up to the network hardware how the packets are routed. If you have the ability to configure routing on the intermediate hardware, you could fix the route the whole way to the destination but this is usually an awful lot of work and likely to be broken when kit is updated/replaced as it's non-standard.
If you decide to look into forcing routes, start with the Windows route command
Edit: Re: Forcing routing over an interface...
the syntax is route add target mask gateway costmetric interfaceid
run route print at a command prompt and make a note of the interface id you want to use form the top of the output
then add a route like this:
route add 10.10.10.2 255.255.255.255 10.10.10.2 1 [interface id from above]
on my machine that would be
route add 10.10.10.2 255.255.255.255 10.10.10.2 1 11
Note that in this case we're telling it to use 10.0.0.2 as a gateway. I have no idea what the consequences of doing this will be as software attempting to access itself via a locally bound port might get very confused. Last caveat: I don't have a pair of physical machines to hand that I can test this on, and VMs don't really count as their networking is slightly different.
We're providing a cost metric of 1. This should give it a very high priority meaning it should be chosen above all other routes to that IP address.
The route will be lost when the system reboots. You can use a -p flag after route add to make the route persistent. I suggest you don't do this until you're sure it's working as intended.
2nd Edit: I think you're heading down a rabbit hole here. While it may be possible to trick the system into working this way, it's definitely not a common usage and I haven't been able to find anything that says it's supported.
It seems like your fundamental problem is that you've got no way to negotiate before assigning IP addresses as you have no network connectivity.
Some thoughts...
Sharing the IP is not going to be robust, so decouple from it. Instead of using a fixed IP in the url, determine the other IP address programatically.
You could have two builds, one which uses .1/.2 and the other which uses .3/.4. Any build1 could then talk to any build2 but not 1-1 or 2-2. This is a bit awkward but would work with little effort on your part.
Better would be to assign unique IPs to every machine you build, then provide a way to detect the other machine's address. Service location protocol is a likely candidate for this approach. Once you know the IP address you need to communicate with, configuring WCF should be trivial.
If assigning unique IPs is problematic, you could potentially have DHCP servers on all nodes but only turn them on if another one doesn't exist on that network (pair). That way, every machine would end up with valid IP addresses with no prior configuration.
Your endpoint address needs to identify the IP address you are targetting.

Round #2: HttpListener not receiving outside requests

Same situation as this question, HttpListener not receiving remote requests, even with the firewall down and all prefixes registered, namely:
the HttpListener is only receiving requests from the same machine
the application is running on a Windows EC2 instance (same spec as the other question)
the ports being used are registered and opened in the firewall (I also temporarily took down the firewall to ensure that wasn't the issue)
The prefix I'm using is http://*:8080/
Differences from the other question:
The security groups of the EC2 are correctly configured
It was accepting outside requests, until (as far as I know) today and I'm not aware of any system changes (but I'm open to all ideas, whatsoever)
Additional info:
The EC2 instance and system is passing all status checks
I restarted the instance; no change
The http status code sent back (not from my server application, from the system) to a remote client is a 503 (service unavailable)
I've checked and rechecked that the url is correct (I have an elastic IP address and am using the public DNS of the instance in the url)
I ran netstat to make sure the port was not being used by other processes
Any ideas for things to check or try are completely welcome; I've pretty much run out of ideas...
If you have more than one urlacl on the same port, e.g. like:
$ netsh http show urlacl
Reserved URL : http://+:8080/
User: PUBEN\myself
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;S-1-5-21-436374069-1547161642-1177238915-5114)
Reserved URL : http://192.168.47.120:8080/
User: \Everyone
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;WD)
Reserved URL : http://127.0.0.1:8080/
User: \Everyone
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;WD)
You will get ServiceUnavailable due to the first reservation in the list. To fix,
netsh http delete urlacl url=http://+:8080/
Or just use Suave.io and save yourself the headache.
Couple of thoughts, some you've likely already checked:
Make sure you can still hit the listener locally on the machine - just to factor out something wrong with the code iteself
Make sure there is nothing else running on that port on that machine
Check the event viewer - any errors in there that may apply? Other events? A recent Windows Update - anything?
Try another port - to rule out port conflicts, try a different one
Make sure you are bound to the prefix: http://*:{your-port-#-here}/ - also, when you make your call HttpListener can be very specific, if you include a trailing slash in the prefix you register make sure you include that in your call, etc.
When you try to hit the machine - what address are you using: an EC2 Elastic IP address, the EC2 public dns, some DNS name you have routed to that machine? I have seen EC2 machines change public IP/DNS after a reboot before, maybe yours has changed?
That's all I can think of for now. Good luck.

Programmatically retrieve disconnected network adapter information in .NET

I have an application written in C# that needs to retrieve information like IP address, subnet mask from a disconnected network adapter.
I've tried using various methods such as WMI and the .NET NetworkAdapter class but they don't return any useful data when the network adapter is disconnected. I'm pretty sure Windows keeps this information somewhere, since I can apply network settings using netsh and it appears correctly in the Control Panel.
One thing that worked for me in XP was to parse the output of the netsh tool and it would return information even for a disconnected adapter. However, this doesn't seem to work on Windows 7.
Win XP output:
Configuration for interface "Local Area Connection 5"
DHCP enabled: No
IP Address: 169.254.0.128
SubnetMask: 255.255.255.0
InterfaceMetric: 0
Win7 output:
Configuration for interface "Local Area Connection 2"
DHCP enabled: No
InterfaceMetric: 5
Any ideas?
NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
and/or
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\*
- List Interfaces
and then
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\\*\Parameters\Tcpip
current settings parameters
if DHCP - ON then only NetworkChange.NetworkAddressChanged because current IP is impossible to define

No response from sever on external IP in client-server IM app

I'm following a tutorial # http://www.geekpedia.com/tutorial239_Csharp-Chat-Part-1---Building-the-Chat-Client.html to try and gather the basics of networking. For those not wanting to hit the jump, it's a quick tut demonstrating how to program a simple client-server-model chat application.
When I try and run the code in the tut, it works fine as long as both the client and the server are on the same network, but the second I try and do it externally (getting a mate to run the client app, and running the server app my side), it all goes to pot. The fact that the code works when in the same network leads me to believe that it's not a coding issue, but an issue with the way my network is set up.
I'm trying to run the server on my IP address at port 21719, which I have opened, but still other people can't connect to my server, not able to get any form of response at all.
The code (from the tut) that is being used for the server to listen to connections is:
public void StartListening()
{
IPAddress ipaLocal = ipAddress; //ipAddress is parsed from txtIP
tlsClient = new TcpListener(ipaLocal, 21719);
tlsClient.Start();
ServRunning = true; //for the running loop
// Start the new tread that hosts the listener
thrListener = new Thread(KeepListening);
thrListener.Start();
}
Now, the tutorial does actually point out that
IPAddress ipaLocal = ipAddress;
Will cause issues on some configurations, and I'm beginning to fear that my configuration may be included in that.
So, does anyone have any solution for me?
Thanks,
Sam
What is the local IP address that you're using? (ipAddress) If it's 127.0.0.1, that's not correct (I don't know how it would work internally either, but Windows seems to use magic from time to time). Also, if you have multiple NICs in your local machine, maybe the port forwarding is only set up to forward to one of them, and you're using the IP of the other?
If that's not the problem, here are a few generic suggestions:
Grab a copy of netcat. It's a small network testing util whose only job is to form a simple TCP connection. That will allow you to eliminate your code as a variable in all this. If netcat can form a connection, then you know the problem is your code. If not, you've confirmed that it's your router.
You can use WireShark (or TShark) to look for ICMP packets. Capture ICMP packets on the remote machine. If you get "Destination Unreachable" from the router, you've again proved that it's your router.
As Spencer said you need to make sure Port Forwarding is setup on your router, to forward all packets that come in on port 21719 to your internal machine. As for exactly how to do that, it's hard to say without knowing what type of router.
Are you having people use your external (internet) IP address? (See yours here.)
Have you pinholed your router to forward all communications from port 21719 to your server?
Some tips:
What kind of operating system are you using? Please check the Scope and/or Profiles (under Advanced tab) of your firewall rule.
While your friend is trying to telnet to the port (connect to the im server) monitor the traffic using Wireshark or Network Monitor (Wireshark have problems with Vista and Win 7). If you don't see anything hitting your machine the problem is probably on the router side. Double check the settings - you said you set the forward rule (NAT) but did it also set the rule on firewall of your router?

Categories