resolved I've resolved the issue turning off Windows firewall
I run the same code on two different computers.
s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
ipep = new IPEndPoint(IPAddress.Any, int.Parse(mcastPort));
s.Bind(ipep);
// setting options
// ................
// s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, option);
if (s.Poll(1, SelectMode.SelectRead))
{
Console.WriteLine("Poll returned true");
} else
{
Console.WriteLine("Poll returned false");
}
On one computer code works fine, so at least SOMETIMES it works.
However on another computer it doesn't work. In one case Poll returns true and in another case Poll returns false; I've used Wireshark to check that on both computers I can see datagrams on the specified connection (mcastGroup, mcastPort, sourceIp). I was thinking that probably on second computer wrong interface is used, so I replaced new IPEndPoint(IPAddress.Any... with new IPEndPoint(IPAddress.Parse("10.11.12.13")... but this doesn't help.
The only difference I can see. On the computer where program works I can see datagrams only when program is launched. On computer where program doesn't work I always see datagrams, even if application is shutdown.
The question is - how can I troubleshot the problem?
i'm sure that there are datagrams in network because I see them in wireshark
i'm sure that my application and wireshark use the same multicastGroup, multicastPort, sourceIp
i'm sure that I'm using the same interface because I provide it explicitly
But Socket.Poll still returns false. What else should I do?
upd Also I noticed in sniffer that computer that doesn't work uses IGMP v2, while computer that does work uses IGMP V3. Probably feature AddSourceMembership is new to IGMP v3 and that's why my program doesn't work? How to force computer to use IGMP v3?
upd I've created another question https://stackoverflow.com/questions/9775405/the-same-udp-multicast-addsourcemembership-code-results-in-completely-different because I think this is not c# or .net problem
Related
If I connect my pc directly to internet everything is ok, however with my router connected the following code get stuck in readline:
`
TcpListener webserver = new TcpListener(IPAddress.Any, 1302);
webserver.Start();
Debug.WriteLine("Started");
TcpClient client = webserver.AcceptTcpClient();
Debug.WriteLine("Client accepted");
sr = new StreamReader(client.GetStream());
sw = new StreamWriter(client.GetStream());
try
{
string req = sr.ReadLine();
Debug.WriteLine("Request: " + req);
if (req != null)
{
//HTTP/1.0 200 OK\n
//+read file to tcpstream
}`
I'm not trying to build a webserver I'm just testing things out with tcp.
If I use http://192.168.1.100:1302/ in a webbrowser or my public IP without the router the webpage loads so I'm guessing it's sg to do with my router or do I have to implement something else?
What I'm seeing is:
readline is stuck(If I refresh the page a few times the GET / HTTP/1.1 gets trough)
If I use read() I see a load of -1
I used wireshark and I'm seeing a lot of greyed out packages and a lot of retransmissions:
wireshark
I'm stuck first I thought I have to implement Upnp or nat punch through, but since some things are getting through I don't think establishing the connection is the problem.
Why are there packet losts? Where should I even start to debug the problem?
UPDATE #1:
The client(chrome webbrowser) is the same computer, but I tried outside computers(with and without behind a router) as well same result.
UPDATE #2: I think I might know what the problem is, I just tried an external webpage tester and there were no problems, so far every device was in the same ISP. I have to try it with vpn or a device that is outside of my ISP network.
I don't know if this is normal or not, but because of packet loss most packets never arrives to my application. This problem is defently caused by my router(and maybe sg. else), but I even tried to connect to my app with other devices in the same ISP same problem. I confirmed this by using vpn and also with another computer using different ISP.
I'm attempting to connect to a remote server using a specific local interface. My logs tell me everything is working as intended, but checking with netstat, every connection is using the default interface.
I'm using the following code to bind a TcpClient to a specific Local Endpoint
Console.WriteLine("Binding to {0}", connectionArgs.LocalBindingInterface.ToString());
client = new TcpClient(connectionArgs.LocalBindingInterface);
Console.WriteLine("Bound to {0}", client.Client.LocalEndPoint.ToString());
Where connectionArgs.LocalBindingInterface is an IPEndPoint specified as such
IPEndPoint[] localEndPoints = new IPEndPoint[2];
localEndPoints[0] = new IPEndPoint(IPAddress.Parse("192.168.0.99"), 0);
localEndPoints[1] = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 0);
The IP addresses listed here are not the actual addresses.
When i check my logs, this is the info I get
Binding to 192.168.0.99:0
Bound to 192.168.0.99:59252
Binding to 192.168.0.100:0
Bound to 192.168.0.100:53527
But when i netstat -n -p --tcp -a I get
tcp 0 0 192.168.0.98:39948 remote_addr_here:443 ESTABLISHED 17857/mono
tcp 0 0 192.168.0.98:60009 remote_addr_here:443 ESTABLISHED 17857/mono
Clearly something's wrong here. None of the ports, nor the interfaces match. Netstat is run as sudo so I can't assume it's wrong. I also tried to manually create a socket, call it's bind method, and set the TcpClient's Client property to the manually bound socket, but I get the same result.
Is there something i'm doing wrong here? Is there a different way to force a Socket to use a specific Local EndPoint on mono?
I'm running this app as a non-root user, mono --version is Mono JIT compiler version 3.2.8 (Debian 3.2.8+dfsg-4ubuntu1.1), server's ubuntu version is Ubuntu 14.04.3 LTS
Edit 1:
Added an extra logging call after calling TcpClient.Connect()
Binding to 192.168.0.100:59000
Bound to 192.168.0.100:59000
After connect bound to 192.168.0.98:55484
Bottom line: you can't do this, not at the socket level.
The routing of outbound traffic is determined by the network routing configuration. You would have to create an explicit routing table entry for your destination to force a specific adapter to be used.
You can bind to a specific IP address, but this only causes inbound traffic to be filtered, i.e. you'll only receive traffic sent to that IP address.
There are related questions you may want to read as well:
How to stop behaviour: C++ Socket sendto changes interface — context is C++ and not constrained to Windows, but it has what is IMHO the most direct, most relevant notes on the topic.
Using a specific network interface for a socket in windows — fairly poor question and answer both, frankly. But it does contain some quotes and links that you might find useful anyway.
Arguably, this question might have been closed as a duplicate of one of those, or perhaps even another similar question. But those two don't really answer the question in an accurate, C#/.NET-specific way, and I didn't actually find any others that seemed any better.
Here is the scenario: I have 5 apps which all share a common DLL which contains P2P networking functionality that I wrote. One of these apps works perfectly every single time, but the others experience the following problem:
On a multicast broadcast our x86 based tablet can send and receive packets fine, but my x64 computer and ARM tablet can only send packets. The only difference is that they use different ports. I thought that must be it, and tried switching the other apps to use the same ports as the working app as a test, but that was a no-go. Here is the relevant portion of code that handles setting up the broadcasting system.
public async Task<bool> Startup() {
if (P2PNetwork.LocalUser == null || this._listenSocket != null)
return false;
ConnectionProfile connection = null;
//See note 1 below
bool gotConnection = TryGetValidNetworkConnection(out connection);
if(!gotConnection)
return false;
this._heartbeatTimer = ThreadPoolTimer.CreatePeriodicTimer(DoHeartbeat, TimeSpan.FromSeconds(10));
var socket = new DatagramSocket();
var stream = await socket.GetOutputStreamAsync(LANBroadcasting.MULTICAST_GROUP_ADDRESS, P2PNetwork.NetworkGroup.SendPort);
this._outStreamWriter = new DataWriter(stream);
this._listenSocket = new DatagramSocket();
this._listenSocket.MessageReceived += OnMessageReceived;
await this._listenSocket.BindServiceNameAsync(P2PNetwork.NetworkGroup.ReceivePort, connection.NetworkAdapter);
this._listenSocket.JoinMulticastGroup(LANBroadcasting.MULTICAST_GROUP_ADDRESS);
DoHeartbeat(HeartbeatFlags.Ping);
return true;
}
NOTE 1: These symptoms were happening before for all 5 applications. At that time I was using the BindServiceNameAsync without any arguments. After extensive research I found a page that suggested that that approach was not good, and that the Windows 8.1 method that takes a connection profile worked more reliably. I checked the profile multiple times and I get the wireless LAN profile, which is correct for both.
In this case (non-working) the tablet's send port is 50011 and its receive port is 50010. The multicast address is ff02::fb (I've tried IPv4 as well, no change) The PC in this case is the reverse of that. I confirmed that the packets are sending via Wireshark.
I also see this line of output via netstat -a on the PC (which is failing to receive)
UDP [::]:50011 *.*
Despite all this looking correct, my PC simply does not get the OnMessageReceived method called (except for the one app which mysteriously works). What should I be looking for that can cause this odd behavior? I tried changing the ports on the working application to see if it would fail but it didn't. I also tried running the app on a different tablet to see if it was just this PC, but I got the same results on the other tablet. Could the app be failing to join the multicast group? How would I know since the method returns void?
After a few days of banging my head against the wall, I finally got the answer. If you experience this problem, go to your Windows Firewall Settings and check what kind of network you are connected to. In my case, the Wi-Fi was a Guest / Public network. Apparently this means that it is considered "Internet" by the Windows Runtime and not "Private Network". In Package.appxmanifest I had the "Private Network (Client and Server)" options selected, but only "Internet (Client)" (which provides outbound access only) and not "Internet (Client and Server)" on all but the one application that was working for some reason.
On a side note: this doesn't explain why the one x86 tablet was still able to receive for all apps. I can only assume this is some kind of driver flaw.
This should really trigger some kind of warning message because this simple setting is way too easy to overlook.
Edit: Yes I know that UDP doesn't technically connect, but you can still use it to set the default target for Send(), which is what I'm doing here.
Basically I have this problem that between calls to MySocket.Send(), MySocket is becoming disconnected i.e. the Connected variable becomes false (I know that Connected isn't necessarily up-to-date, but no data isn't being sent so I know that it's telling the truth).
The strange thing is that the RemoteEndPoint variable is still set correctly, but when I call Send(), no data is recieved by the other computer. However if I call Connect() again, the socket does connect, and I'm able to send data (at least until the next time the user does something that causes another call to Send() )
Can anyone tell me why a socket would spontaneously disconnect?
The line where I connect it is:
opep = new IPEndPoint(Opponent.Address, 1000);
Listener.Connect(opep);
I don't see anything here that could be garbage collected for example to cause this issue.
Thanks!
UDP doesn't set up a connection. You should check out the following link for more info
Difference between TCP and UDP?
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?