Xamarin forms IOS socket dosn't connect after restart - c#

My Situation.
Im Building a Xamarin Forms V5.0.0.2291 App. When i deploy this app on my physical device, the following code opens a TCP connection to my PC
do
{
try
{
socket = new Socket(EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
result = socket.BeginConnect(EndPoint, null, null);
success = result.AsyncWaitHandle.WaitOne(10000, true);
if (!socket.Connected)
{
socket.Dispose();
ConnectionLost?.Invoke(this, null);
}
}
catch { }
} while (!socket.Connected);
After i Restart the device and open the App again, it displays a permission popup with "your App" wants to find deviceses in you local network etc....
the code above is wrapped in a while loop and only exits when its truely connected.
I confirm this popup but nothing happends anymore. it cannot establich a connection.
On the IOS Simulator it works without problems but on the physical device it does.
In the Privacy settings my app has the permission granted.
I've already googled a lot but I just can't find anything and I'm slowly running out of ideas..
The concrete Question is:
What do i need do too, to establish a connection even though this code works on Android and IOS simulator perfectly?

Related

UdpClient does not receive any data in UWP app

I have a UWP app that needs to use UdpClient to receive some data. The code looks very similar to this:
var udp = new UdpClient(port);
var groupEP = new IPEndPoint(IPAddress.Any, port);
while (true)
{
Trace.WriteLine("Waiting for broadcast");
byte[] bytes = udp.Receive(ref groupEP);
Trace.WriteLine($"Received broadcast from {groupEP} :");
Trace.WriteLine($" {Encoding.ASCII.GetString(bytes, 0, bytes.Length)}");
}
When I run this code in UWP app it stops at Receive(), does not receive anything, and there are no exceptions.
If I run the same exact code in NET 5 console app everything works fine.
How can I make this code run in UWP app?
A common reason for such kind of network issue is the local network loopback. UWP apps are running in the sandbox and are isolated from the system resources like network and file system. In other works, UWP apps are not allowed to access the local host address by default. Enabling the local network loopback could make UWP apps able to access local network resources.
Please also make sure that you've enabled the enterpriseAuthentication and privateNetworkClientServer capability in the manifest file.

How to debug connection to MQTT server using Xamarin System.Net.Mqtt on Android?

I'm trying to build a simple MQTT application using Xamarin, and testing it on both an Android emulator and a phone. Unfortunately, I'm struggling to make a connection with CreateAsync, and at a loss how to debug it.
I've checked I can connect to my RabbitMQ server as follows:
using System.Net.Mqtt;
Console.WriteLine("Trying to connect...");
var configuration = new MqttConfiguration();
var client = MqttClient.CreateAsync("127.0.0.1", configuration).Result;
var sessionState = await client.ConnectAsync(new MqttClientCredentials(clientId: "test", userName:"mqtt", password:"mqtt"));
Console.WriteLine("...it worked.");
Console.Read();
As the code tells me... it worked. :o) RabbitMQ shows the connection. I tried it with "localhost", the hostname and IP of my PC to check they all work, and an incorrect host name to see what exception gets thrown ("Socketexception: No such host is known").
My troubles start when I try to do this in the actual app. The connection code is fundamentally the same, but run in a separate task as I read you shouldn't do it in the GUI thread:
private async Task<SessionState> Connect(string BrokerHostName, Action<MqttApplicationMessage> publishEventHandler)
{
MqttConfiguration config = new MqttConfiguration();
_client = MqttClient.CreateAsync(BrokerHostName, config).Result;
SessionState sessionState = await _client.ConnectAsync(
new MqttClientCredentials(clientId: Id, userName: "mqtt", password: "mqtt")
);
await _client.SubscribeAsync("common", MqttQualityOfService.AtMostOnce);
_client.MessageStream.Subscribe(publishEventHandler);
return sessionState;
}
Called by:
var task = Connect(BrokerHostName, publishEventHandler);
But nothing happens - the code reaches this line and just hangs. If I set a break, continuing just continues to do nothing. I've made sure the INTERNET and ACCESS_NETWORK_STATE permissions are ticked in the Android manifest (though it makes no apparent difference).
This is what I've tried after some hours of Googling:
Using the hostname or IP address of my PC with the Android device, running with and without debug, and also unplugged from PC and run on its own.
Using 10.0.2.2 and running on the emulator, as I understand this is the equivalent of localhost or 127.0.0.1.
Setting the proxy address on the emulator to the same as my PC and port 1883. Even though the 'Apply' button teases with a "Proxy status: success", it still doesn't connect.
It feels like a networking problem since I can put any old rubbish as the host address and it behaves the same, but I've totally run out of ideas for what to try next or how to see what's going on. Any advice very gratefully received!
I now have this working. Here's the steps I took, in case it helps someone else:
I wrote some test apps to check TCP communication. First a client and server in Windows to check they work, then a Xamarin client app. This worked and proved the network connections were OK.
Installed an MQTT Tester on the Android emulator to prove it was possible to connect to RabbitMQ.
Tried a different MQTT framework: MQTTnet.
Similar problem but different symptoms: the code would get stuck on the .Wait() rather than inside the task itself. Then I removed all the asynchronous code and then it connected.
My conclusion is that the problem may be my lack of understanding of asynchronous programming. System.Net.Mqtt seems to require it while MQTTnet does not, so all's well that ends well!

C# TCPListener stops listening after idle phase

I'm trying to figure out why my clients sometimes cannot connect to the Server after the listener was running some time without any client tried to connect.
The only way to fix it, is to restart the TCP listener - the server.
There are no issues if I start the server and some people connect, do stuff and disconnect later.
I have a simple while loop to accept the incoming socket connections:
while (IsOn)
{
try
{
if (!tcpListener.Pending())
{
Thread.Sleep(100);
continue;
}
Socket socket = tcpListener.AcceptSocket();
if (socket != null)
{
TcpClient client = new TcpClient();
client.Client = socket;
IncommingClientConnection(client); // Nonblocking Code
}
}catch(Exception e)
{
NetLog.Exception(e, "An error occured while user connected!");
}
}
The last time the error occured was after around 8 hours of idle time. Sometimes it happens earlier.
I tried to debug this issue but the listener thread was still running and it seems like it hangs on
tcpListener.AcceptSocket()
.
I've read that this could be fixed by setting up a Windows Service but this would be a lot of work for now. But isn't there any other way to force the Listener to stay opened?
Any suggestion is highly appreciated, thanks!
I figured out what the error was. It is so ridiculous because why should a freezed thread has something to do with "Console.WriteLine()"?!
The Problem was, that the Console Window on Windows Server 2016 somehow changes to input mode. The thread then blocks on "Console.WriteLine" and waits for the user to press Enter on Console Window?! I tried some scenarios. Even If I did not touch the Remove-Desktop for some time this issue occured.
Solution: Switch from Console Application to Windows Application and track output in the integrated Console-View of your IDE.
I hope this helps someone...

Notification of Bluetooth connection in UWP app

I'm using Windows.Devices API in a WinForms App on Windows 10. I'm connecting to a Bluetooth Barcode scanner. The connection works fine and I'm getting an Event when the connection has been established and also when the connection has been dropped (disconnected).
But when I change the battery in the scanner and the scanner re-connects to Windows I'm getting no Event.
My question now is: if there's any possibility to get an Event when the device re-connects over Bleutooth?
My need is to reconnect the socket to the device after the device has been reconnected over Bluetooth.
EDIT: Dear admins, this is not a WinForms issue. This issue even doesn't deal with UI at all. It's just an API issue with the Windows.Devices UWP API. Please stop suggesting changing the tags.
Thanks
Sven
Some Sample Code:
_device = await BluetoothDevice.FromBluetoothAddressAsync(decimalAddress);
_device.ConnectionStatusChanged += OnDeviceConnectionStatusChanged;
Event is called only on first connect and on disconnect of device:
private void OnDeviceConnectionStatusChanged(BluetoothDevice sender, object args)
{
}
What I've found out so far is that it seems very common that the event never raises again. One has to actively create a new connection to the device, that is, for example by opening a socket for receiving data.
So the solution for my problem was to connect to the bluetooth device by calling
StreamSocket.ConnectAsync()
again to establish a new connection. Afterwards the ConnectionStatusChanged is raised with state connected.
Good luck
Sven

C# Custom Remote Desktop Client using RDP 8.0

I have searched MSDN forum for this, but it seems everyone(i think) suggests to revert to RDP 7.x (uninstall MS Update KB2592687).
I have an custom Remote Desktop client written in C#/WPF,the Remote Desktop ActiveX control is hosted inside a WindowsFormsHost control.
The app works well prior to update RDP 8.0 (MS Update KB2592687). If i uninstall the MS update(revert to RDP 7.1), the app works.
My RDP Client is used to connect to Virtualbox VRDP (Virtualbox 4.2.x), no authentication needed(Null). With RDP 8.0 installed, the Windows Remote Desktop Client(mstsc.exe) connects just fine, with much better responsiveness(RDP 8.0 enhancements); but my custom RD Client is unable to connect.
Upon further investigation, my custom RDP Client is not throwing any exceptions or firing the OnConnecting and OnLogonError or most of the other events.
What's odd is, it is ONLY firing these two events (in order)
OnAuthenticationWarningDisplayed
OnAuthenticationWarningDismissed
I also tested with RawCap(http://www.netresec.com/?page=RawCap) to see if my custom RDP Client is sending packets to Virtualbox VRDP prior to those events. Surprisingly, it's not even sending packets. (MS RD Client - mstsc.exe works fine.)
So it boils down to these events/method calls on my custom RDP Client, and unfortunately I'm stuck.
(Code is shortened for brevity)
AxMSTSCLib.AxMsRdpClient8 rdp = new AxMSTSCLib.AxMsRdpClient8();
rdp.OnAuthenticationWarningDisplayed+=new EventHandler(rdp_OnAuthenticationWarningDisplayed);
rdp.OnAuthenticationWarningDismissed+=new EventHandler(rdp_OnAuthenticationWarningDismissed);
rdp.Server = server;
rdp.AdvancedSettings8.RDPPort = 5050;
//No username/password since Virtualbox RDP authentication is set to *null*
//MS RD Client connects just fine to Virtualbox RDP without username/password
try
{
rdp.Connect();
}
catch (Exception ex)
{
}
putting a breakpoint on OnAuthenticationWarningDisplayed and OnAuthenticationWarningDismissed confirms both events are fired after Connect() method.
I suspect the ActiveX control, after the Connect() method is called, is trying to show a dialogbox(??); but i can't seem to figure out.
Has anyone else done some custom client using RDP 8.0? What are the prerequisites to have it working(code).
Many thanks! Would greatly appreciate it.
Solved this problem!
Just try to use AxMSTSCLib.AxMsRdpClient8NotSafeForScripting instead of AxMSTSCLib.AxMsRdpClient8
Here's working code (Delphi):
rdp:TMsRdpClient8NotSafeForScripting; // ***Instead of TMsRdpClient8 (!!!)***
...
if rdp.Connected<>0 then rdp.Disconnect;
rdp.Server:='192.168.1.1';
rdp.UserName:='User';
rdp.AdvancedSettings8.ClearTextPassword:='Password';
rdp.AdvancedSettings8.AuthenticationLevel:=2;
rdp.AdvancedSettings8.EnableCredSspSupport:=true;
rdp.AdvancedSettings8.NegotiateSecurityLayer:=false;
rdp.AdvancedSettings8.RelativeMouseMode:=true;
rdp.AdvancedSettings.BitmapPeristence:=1;
rdp.AdvancedSettings.Compress:=1;
rdp.AdvancedSettings8.SmartSizing:=true;
rdp.DesktopHeight:= Screen.Height;
rdp.DesktopWidth:= Screen.Width;
rdp.FullScreen:=true;
rdp.ColorDepth:= 15;
rdp.AdvancedSettings8.RedirectDrives:=false;
rdp.AdvancedSettings8.RedirectPrinters:=false;
rdp.AdvancedSettings8.RedirectClipboard:=true;
rdp.AdvancedSettings8.RedirectSmartCards:=false;
rdp.Connect;
P.S. And do not use the following property:
rdp.AdvancedSettings8.AuthenticationServiceClass

Categories

Resources