WCP WebHttpBinding times out on machines on the same LAN - c#

I'm currently attempting to add a simple WCF-based web UI to an existing application, so that certain aspects can be remote controlled via any device on the same LAN with a web browser. (from a phone or tablet 30ft away via WiFi, for instance) This works for the most part, from the same machine, at least, but if I try and connect from any other device, it just times out.
WebHttpBinding binding = new WebHttpBinding();
binding.TransferMode = TransferMode.Streamed;
WebHttpBehavior behavior = new WebHttpBehavior();
WebServiceHost host = new WebServiceHost( typeof( Service ), new Uri( "http://localhost:8000/[REMOVED PRODUCT NAME]" ) );
host.AddServiceEndpoint( typeof( IService ), binding, "" ).Behaviors.Add( behavior );
host.Open();
This is self-hosting from C# on Windows 7 64 bit.
I have added a firewall exception and the program to the netsh ACL.
I can ping the host device from the client device.
I can still get to it from the host device if I go via LAN IP rather than localhost.
I have added a parameterless constructor and finalizer to the Service class which print to Console so I can tell if and when it is being constructed by WCF. This happens when accessed locally but not from another device on the same LAN, suggesting the problem lies with the binding to me.
Thank you.

Resolved; the issue is down to the router in use seemingly firewalling users from one another. Using another router or ethernet cable works.

Related

WCF Endpoint Address using https (WebHttpBinding)

I need to modify a WCF endpoint binding address. Here is some background on the issue:
I have an NT class service (if it matters, not a webservice). It creates a System.ServiceModel.ServiceHost with an Endpoint whose endpoint address is created this way:
var epa = new EndpointAddress(string.Format("https://localhost:{0}/ServiceAPI/", 8181));
The binding used for the ServiceEndpoint is a WebHttpBinding with Mode=WebHttpSecurityMode.Transport (i.e. https).
When the ServiceHost is opened, I can go to a command prompt, and do "Netstat -a" and see the address bound to the Listen as 0.0.0.0:8181.
So far, no problem. However, a large customer has raised a "security issue" with the fact that because the WCF "listen" is on address 0.0.0.0 instead of 127.0.0.1, that a potential attacker can connect to that address from an external machine. The test that they have constructed is to use telnet 8181 from an external machine, and if the connect occurs, then the test fails. The change request is to modify the service to "listen" on 127.0.0.1:8181 so that the only possibility of connecting to that port is from the local machine.
I have done a fair amount of modifications in an attempt to get WCF to "listen" on "127.0.0.1" instead of "0.0.0.0". In all of my attempts the only way to do this is to set HostNameComparisonMode to "Exact" and create the endpoint address in this way:
var epa = new EndpointAddress(string.Format("https://127.0.0.1:{0}/ServiceAPI/", 8181));
(Actually, as an aside, if I use a different binding such as NetTcpBinding, the above EndPointAddress construction will bind to address "127.0.0.1:8181" without altering HostNameComparisonMode. It only switches internally to "0.0.0.0:8181" when I use WebHttpBinding, and fail to set HostNameComparisonMode=Exact.)
However, this (setting HostNameComparisonMode=Exact) causes a breaking complication due to the fact that existing 3rd party code has already been developed that attempts to (onboard the server) connect to "https://localhost:8181/ServiceAPI", and when HostNameComparisonMode is set to "Exact", WCF only ever returns http error 506 to any request due to the difference between "localhost" and "127.0.0.1".
What I am currently looking for is either a means of setting up WCF to bind to "127.0.0.1:8181" (as determined by netstat -a) with the HostNameComparisonMode still set to the default "StrongWildcard" setting. Or barring any possibility of there being a way to do that, another creative suggestion to cause connects coming from external machines to be unable to connect to that port. (The test would be to use "telnet servername 8181" from a different machine, and it fail to connect.)
Any ideas? Thanks!
if i understand you right, you want to connect from remote machine to this address, so can you try BasicHttpBinding? Also you can try to host it at: "https://localhost:{0}/ServiceAPI/", 8181" Correct pls if i understand you wrong.

'No connection could be made because the target machine actively refused it'

I am working on a 'Smart Device Project' using .Net Framework 3.5. I am trying to connect to some Java SOAP services on a remote server.
In order to do that, I added 'Web References' to my project.
When I try to call my web service I get a WebException 'Unable to connect to the remote server' with the inner exception being 'No connection could be made because the target machine actively refused it'.
I searched quite a lot on the Web and StackOverflow and found a lot of ASP configuration and 'Unavaliable port' answers, but as I have another application using the exact same Service successfully, I can't get why the new one isn't getting through (It did sometimes through my tests so I suppose my client implementation isn't that bad)
I tried to look if there was some connection issue on the port by using some TcpClient:
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
try
{
client.Connect("myServerName", 8087);
MessageBox.Show("Success");
} catch (Exception ex)
{
MessageBox.Show("Failure");
}
finally
{
client.Close();
}
This connection succeed.
Here is a sample on how I call my WebService:
WSServiceExtended srv = new WSServiceExtended();
srv.Proxy = new System.Net.WebProxy();
ServeurWSI wsi = new ServeurWSI();
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
wsr = srv.login(wsi);
The service is called 'Extended' because I overrided the auto-generated one in order to add Cookie managment since I am using the Compact Framework. Following the sample in this thread:
https://social.msdn.microsoft.com/Forums/en-US/34d88228-0b68-4fda-a8cd-58efe6b47958/no-cookies-sessionstate-in-compact-framework?forum=vssmartdevicesvbcs
EDIT:
I made some new tests with the Web references and got it to work.
When I add the Web Reference, I have to put some Url to the Web Service. When I set it with the actual hostname instead of the 'localhost' everything is fine.
But then, since I set it manually to the real address just before the call, it shouldn't matter
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
EDIT2:
I might have forgotten some specifics about my environnement.
The Web Services are exposed on my computer on some Tomcat Server.
The application I am working on is also developped on this computer (That's why I can add Web References by putting 'localhost' in the address)
The application is then deployed on a distant device (Windows CE) that will make calls the Web Services through WIFI (There, localhost wouldn't work then)
I tried calling the Web services from other computers successfully.
I'm beginning to think that there might be some differential between the called Url and the one that is set, otherwise, how would I have a difference in behaviour such as the one described in the first edit?
EDIT3:
Well..Seems like it's not a network issue but a .Net compact framework (usage?) issue...
The Url property of the Web Service implementation is simply ignored and the one in the Reference.cs is used in place.
If someone had some idea on how I could troubleshot this, I would really appreciate it.
That error means that you reached a server and the server said "no way". So you're either hitting the wrong server or the wrong port.
I find the telnet client is useful for testing stuff like this. From the command line, you can do:
telnet [servername] [port]
So something like:
telnet myServerName 8087
If it goes to a blank screen, then it connected successfully. If it does not connect, it'll tell you.
The telnet client is no longer installed by default in Windows 7+, so you'll have to install it. See here for instructions: https://technet.microsoft.com/en-ca/library/cc771275
If the connection does open, you could paste in an actual HTTP request to see what happens. A simple GET would look something like this:
GET /myServerApp/services/myService HTTP/1.1
Host: myServerName:8087
One reason for this error can be that the service binds to only a certain IP address. It could well be that the service only listens on the IP that is assigned to the host name, but not on the localhost IP (127.0.0.1).
For example:
If the host myServerName has the public IP 192.168.0.1, your service can choose to listen on all IPs assigned to the host (sometimes specifying 0.0.0.0), or it can specifically listen on 192.168.0.1 only. In that case you will not be able to connect through 127.0.0.1, because the service simply doesn't listen on that IP.
You can "use" this inverse of this feature to make a service accessible only to local clients, not on the public IP-Address, by listening on 127.0.0.1 only, but not on the public IP. This is sometimes used on Linux for example to make MySQL only accessible on the host itself.
I was starting to forget this post but I finally found the problem that was messing things up and it has nothing to do with programmation.
I was doing the calls while the device was connected to the computer via the 'Windows Mobile Device Center' allowing to access the device from Windows.
While connected, the host provided is ignored and all calls on the specified port are handled by the connected computer.
Disconnecting the device allows to communicate properly...

WCF error "no endpoint listening" with named pipes

I'm using WCF with .NET 3.5 I am using named pipes but keep getting the error
There was no endpoint listening at
net.pipe://localhost/Test that could
accept the message. This is often
caused by an incorrect address or SOAP
action.
I followed the tutorial http://www.switchonthecode.com/tutorials/wcf-tutorial-basic-interprocess-communication but the problem remains. The endpoints on both the client and server are the same (I checked spelling etc). There is no config file for this project but the config is in the code.
EDIT: Code (client):
ChannelFactory<ITest> pipeFactory =
new ChannelFactory<ITest>(
new NetNamedPipeBinding(),
new EndpointAddress(
"net.pipe://localhost/test"));
ITest test= pipeFactory.CreateChannel();
test.doStuff();
SERVER:
serviceHost = new ServiceHost(typeof(Test), new Uri("net.pipe://localhost"));
serviceHost.AddServiceEndpoint(typeof(ITest), new NetNamedPipeBinding(), "test");
File.Create(#"C:\test.txt");
serviceHost.Open();
Thanks
On the server side don't include base addresses when you create the ServiceHost instance. Instead, provide the fully qualified endpoint address when you add the service endpoint:
serviceHost = new ServiceHost(typeof(Test));
serviceHost.AddServiceEndpoint(typeof(ITest), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/test"));
File.Create(#"C:\\test.txt");
serviceHost.Open();
This could be:
You are running it as a windows service and the service is not running
You are running it as a console app and there is no console.readline, so it just exists
You are running client and server on two different machines so that localhost is not going to the machine with the service.
Another possibility to fix this root issue if you are getting an error that no net.pipe address can be found at your url (i.e. http://localhost:1234/MyService/etc/) is to make sure that the Net.Pipe Listener Adapter Windows Service is started. (I also started Net.Tcp Listener Adapter)
The service does not seem to be enabled or started in some scenarios especially when deploying out to a remote server that might not of had a lot of the development tools installed that actively use these services. Starting the service fixed the issue.

WCF listen base address anyip

i want my servicehost to have the base address of any IP
so i tried this
new ServiceHost(typeof(LoggingController),new Uri("0.0.0.0"));
and it gives me invalid URI format
any one knows how should i write this ?
well i tried to access it from outside of my local lan and it didnt work , i made a small test software using tcpiplistener and i started listening to the same port and i set the base address of the tcpip protocol to anyip and the small test software worked so i figured out all i need to do is setting the same for the Webservice –
TcpListener tcpListener = new TcpListener(IPAddress.Any,10021);
this works which also mean my system admin did his job of making sure the port/server is accessable from outside, now shouldnt my webservice work !? it work but i cant access it from outside , i can access it from the same pc if i run client on the same pc
The following code works for me in a similar situation:
Uri baseAddress = new Uri("net.tcp://0.0.0.0:8080/MyService");
host = new ServiceHost(typeof(MyServer), baseAddress);
Reminds me of a problem we had with our software. The default configuration of the webservice used windows network credentials to apply message based security which - due to the domain/network credentials - won't work from another network. Our solution was to disable security on the service binding (which may be a bit tricky depending on the binding you use). For the default bindings like WebHttpBinding it's just passing a parameter in the constructor.
Hope this helps!

Can two applications share same WCF NetTcpBinding port if they use different end point addresses?

I have a Client and Server scenario, where a service is installed on the client and another service on the server. I have no issues when these are installed on different machines. However, I would like to also be able to install both the Client service and Server service on the same machine. I could set them up to use different ports, however I would like to accomplish this using a single port.
I have enabled and started the Net.Tcp Port Sharing Service Windows service. I start up the Server service first. When I attempt to start the Client service I get the following exception upon executing serviceHost.Open():
The TransportManager failed to listen on the supplied URI using the NetTcpPortSharing service: the URI is already registered with the service.
Below is the source code. Both Server and Client use different end point addresses as follows:
Server Service:
ServiceHost serviceHost = new ServiceHost(typeof(ServerService),
new Uri("net.tcp://localhost:50000");
NetTcpBinding binding = new NetTcpBinding();
serviceHost.AddServiceEndpoint(typeof(IServerService),
binding, "ServerService");
serviceHost.Open();
Client Service:
ServiceHost serviceHost = new ServiceHost(typeof(ClientService),
new Uri("net.tcp://localhost:50000");
NetTcpBinding binding = new NetTcpBinding();
serviceHost.AddServiceEndpoint(typeof(IClientService),
binding, "ClientService");
serviceHost.Open();
I just resolved it making the base Uri's different during instantiation of the ServiceHost. Revised code follows:
Server
ServiceHost serviceHost = new ServiceHost(typeof(ServerService),
new Uri("net.tcp://localhost:50000/Server");
...
Client
ServiceHost serviceHost = new ServiceHost(typeof(ClientService),
new Uri("net.tcp://localhost:50000/Client");
...
This should also help...working version of TCP port sharing done in Code (vb.net)
http://softwarebykarl.wordpress.com/wcf-shared-tcp-port-in-code/

Categories