My intention is to receive UDP messages over the internet on a windows phone 8.
-> First question: am I wrong assuming that this is possible?
Test setup:
WIFI switched off, cellular data on
Running NetworkInformation.GetHostNames() I get one host with IANA network code 344, IP Address was "10.146.8.159".
Opening icanhazip.com at the same time in the browser I get an IP Address of "192.230.159.176".
-> Second question: why are these two IP addresses different?
My code is:
public async void Start()
{
m_rxSocket = new DatagramSocket();
m_rxSocket.MessageReceived += MessageReceived;
await m_rxSocket.BindServiceNameAsync("57000");
}
private async void MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs socketEventData)
{
// This is never called
}
The problem is that the method MessageReceived is never called despite:
Sending a UDP message to 10.146.8.159 as well as 192.230.159.176 over the internet
Registering the ID_CAP_NETWORKING
-> Third question: why is no message received by the setup above?
(-> Fourth question: anyone else thinking that wp development with silverlight was superior to this new apis that are smelling C++ all over...?)
Hi i have found what was wrong:
Lack of UDP hole punching was the reason for the behaviour and adding UDP hole punching the solution to make it work.
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.
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.
So now I'm building a ISO8583 Payment Gateway application. This application is a client-server application that can act as a client or server. In this case, I'm handling the client side of the application.
At first, I connected the (client)app to a external server. I was sending inquiry message and it ran well (returning success message). Then, i'm trying to run this app as both client and server (run 2 apps and set my ip as ip host), one as client and the other one as a server. I'm sending inquiry message and it keeps returning response code 67 (other error). Meanwhile it's succeed when I run the app as client only.
I don't know if it helps but here's the inquiry method
/// <summary>
/// Send Inquiry Message
/// </summary>
private void SendInquiryMessage()
{
var requestMsg = new Iso8583Message(200);
DateTime transmissionDate = DateTime.Now;
requestMsg.Fields.Add(7, string.Format("{0}{1}",
string.Format("{0:00}{1:00}", transmissionDate.Month, transmissionDate.Day),
string.Format("{0:00}{1:00}{2:00}", transmissionDate.Hour,
transmissionDate.Minute, transmissionDate.Second)));
requestMsg.Fields.Add(11, _sequencer.Increment().ToString());
requestMsg.Fields.Add((int)ISO8583ProtocolFields.PROCESSING_CODE, "341019");
requestMsg.Fields.Add((int)ISO8583ProtocolFields.ADDITIONAL_DATA_61, "5271720012002010802012");
#region Send 0200
SendRequestHandlerCtrl sndCtrl = _client.SendExpectingResponse(requestMsg, 1000, true, null);
sndCtrl.WaitCompletion(); // Wait send completion.
if (!sndCtrl.Successful)
{
Console.WriteLine(string.Format("Client: unsuccessful request # {0} ({1}.",
_sequencer.CurrentValue(), sndCtrl.Message));
if (sndCtrl.Error != null)
Console.WriteLine(sndCtrl.Error);
}
else
{
sndCtrl.Request.WaitResponse();
if (sndCtrl.Request.IsExpired)
_expiredRequests++;
else
_requestsCnt++;
}
latestInquiryMessage = sndCtrl.Request.ReceivedMessage as Iso8583Message;
Console.WriteLine(latestInquiryMessage.Fields[39].Value);
#endregion
}
Anyone know what the problem is? What I could possibly miss?
Thank you!
I don't know which specific ISO-8583 implementation you are attempting to write to but a couple guesses based on what I do see or do not see and what your actual question is.
It seems especially odd that it works when it communicating with the remote server as client but not as both. Where is your communications configuration?
This points to your TCP/IP configuration and my guess is that you are attempting to listen and communicate on perhaps the same port so are not truly completing the TCP/IP handshake. While I believe you technically can listen on a port and communicate out it for a different process I think it unnecessarily complicates things.
So my guess is that what is happening and is your problem is that you are attempting to communicate with yourself, are maybe not getting fully connected and instead of saying "91 - Issuer Not Available" or "96 - System error" it is giving you the odd "67 other error" as it may not have been able to actually send it.
Do you have trace, or have you watched the connectivity with netstat -a 1 or even better Wireshark if you do not have trace to verify that you are getting fully established?
I'm experiencing an issue specific to Windows 8 and VS2012.
I have a TCP socket server and client and am doing some testing on the local network. With sysinternals TCPView, I can see that packets are sent from the TCP client and arrive at the TCP Server (I see the packet counters increase).
However, it appears as if the data is not making it to the application stack?
The very same build runs without issues on Windows 7.
I have the Windows 8 firewall turned off and run both process with elevated permissions on a domain admin users with UAC turned off.
When I connect the client to a an outside server (running on a separate machine), everything works fine.
Is there anything else in Windows 8 that could prohibit TCP data communication between local processes?
Thanks,
EDIT
To make sure nothing in my server application is causing this issue, I built a quick TCP server in a console application, with the following code for the socket constructor:
listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
and listen on the same local IP/Port as my server application.
I'm experiencing the same issue, I can telnet to the port but listenerSocket.AcceptAsync is never hit.
EDIT 2
Upon further testing, it appers my issue has something to do with the use of the Async socket calls, i.e. if I use the synchronous calls like socket.Accept(), the test application is performing normally. However, when I use Async socket calls, i.e. socket.AcceptAsync(), I'm experiencing the issues mentioned. So far I couldn't find any mention of differences between win7 & 8 in regards to async socket calls.
Here's my quick sample app that shows that the async callback is never triggered. This snippet works fine in Windows 7 but does not work in Windows 8 (try to telnet to 127.0.0.1 : 7000).
class Program
{
private static SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();
static void Main(string[] args)
{
var listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenerSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7000));
listenerSocket.Listen(100);
socketAsyncEventArgs.Completed += AcceptEventArg_Completed;
listenerSocket.AcceptAsync(socketAsyncEventArgs);
Console.ReadLine();
}
private static void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
Console.WriteLine("AcceptEventArg_Completed");
}
}
EDIT 3
I found 2 others reporting the same issue on Microsoft Connect:
https://connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5
and
http://connect.microsoft.com/VisualStudio/feedback/details/747218/saea-not-working-in-net-4-5-rp
Whereas the 2nd one is interesting as it seems to conclude there is a Windows bug in the Console.ReadLine() call and it is causing the issue and blocking the async callback. If I replace Console.ReadLine() in my snippet with:
while (true)
{
System.Threading.Thread.Sleep(10);
}
everything works fine.
See this: GetQueuedCompletionStatus can't dequeue IO from IOCP if the thread which originally issued the IO is blocking in ReadFile under windows 8
It's a bug in windows 8 and 2012 and affect all programs which used AcceptEx and ReadFile. As for now, only these two functions are known affected.
I meet the same thing when I was developing Tcp server and client applications with SocketAsyncEventArgs
I suggest you try this first.
open Windows firewall with Advanced Security
check the inbound / outbound rules to see if your application is blocked.
open AssemblyInfo.cs and change the
[assembly: Guid("06985fe3-80eb-48b4-940a-fd926e2f2053")]
to any other guid value.
By changing this, windows will think this is a new application and if there were any restrictions towards the old application, it wont be on the new one.
Sounds like this windows bug relating to the IOCP processing (possibly just of AcceptEx) on Windows 8 while other blocking I/O is in progress on the same thread:
http://social.technet.microsoft.com/Forums/en-GB/winserver8gen/thread/5764cd0f-fda1-4cfa-ae35-808210bae77e
So the socket connection is accepted, but your app never recieves notification of it.
Maybe Windows 8 does some weird, slighly broken, voodoo to convert synchronous IO like Console.Read into async internally.
You could just move your server code into a different thread, other workarounds to try might be to perform Accept synchonously or to change the console processing to be asynchronous (I can't really try that as I don't have Windows 8).
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?