Timeout in socket connection in UWP - c#

I have this code which works fine for project type of Console App (.NET Core).
class Program
{
static void Main(string[] args)
{
var L = new TcpListener(IPAddress.Any, 4994);
L.Start();
using (var C = L.AcceptTcpClientAsync().Result)
{
var S = C.GetStream();
var BR = new BinaryReader(S);
var BW = new BinaryWriter(S);
BW.Write("This is from Console!!!");
Console.WriteLine(BR.ReadString());
}
}
}
But when I use this code in project type of Blank App (Universal Windows) like this:
public MainPage()
{
InitializeComponent();
ThreadPool.RunAsync(foo);
}
static void foo(IAsyncAction operation)
{
var L = new TcpListener(IPAddress.Any, 4994);
L.Start();
using (var C = L.AcceptTcpClientAsync().Result)
{
var S = C.GetStream();
var BR = new BinaryReader(S);
var BW = new BinaryWriter(S);
BW.Write("This is from UWP!!!");
Debug.Write(BR.ReadString());
}
}
It will listen to that port when I check it by netstat but when the client wants to connect this exception will be thrown.
System.Net.Sockets.SocketException: 'A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond'
The UWP App has Private Networks (Client & Server) and Internet (Client & Server) capabilities.
Turning firewall on and off didn't help.
Target Version: Windows 10 Creators Update (10.0; Build 15063)
Client Code which is a WPF application:
using (var C = new TcpClient("127.0.0.1", 4994))
{
var S = C.GetStream();
var BR = new BinaryReader(S);
var BW = new BinaryWriter(S);
BW.Write("This is a test");
MessageBox.Show(BR.ReadString());
}

Debugging UWP & TCP listeners from localhost has always been problematic. Your code is OK and it should work if you try to connect into it from an external computer. The issue you're seeing is quite likely a bug/hyper-v issue/networking problem in the network isolation.
You can check if the network isolation for your app is enabled (it is by default) running the following from command prompt:
CheckNetIsolation.exe LoopbackExempt -s
My recommendation is to use an external computer to make sure that your code is fine (it should be). After that you can try to fight with the network isolation but that can be frustrating.
Here's an another issue where this has been discussed: Unable to access TCP Server inside a Windows Universal Application

Related

C# multi-hop SSH (SSH through SSH)

I wrote a C# console program to connect from A (Windows 10, Console C# app) over SSH to B (Linux server) and from there on to C (Linux server), but I cannot connect from B to C (from A to B is ok).
When I connect from A over Windows terminal to B and from B's terminal to C, it works, so I proved that my credentials are fine.
I am using Renci.SshNet for C#
I created a class Server with a .Connect(), .Disconnect() and .Execute() extension methods and then the two class instances Broker and Destination
My code looks like:
if (Broker.Connect())
{
Broker.Execute("pwd");
if (Destination.Connect())
{
Destination.Execute("pwd");
Destination.Disconnect();
}
Broker.Disconnect();
}
The Ssh connection objets are created like var broker = new SftpClient("Ip", Port, "User", "Pass")
Then I am internally using broker.Connect() and broker.Disconnect() in Renci.Ssh.Net lib given methods
To broker.Execute("cmd") I basically do
var output = host.Ssh.RunCommand(str);
var res0 = output.ExitStatus;
var res1 = output.Result;
var res2 = output.Error;
My code works for the first part as I manage to get the output of Broker.Execute("pwd") but it does not connect on Destination.Connect() returning the message A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
My aim ist to multi-hop using an automated process from within C#: users must not interact with any console and I cannot modify nor store any files on the Linux sites
Any idea where the problem lies?
Thanks in advance,
I will like to summarize here how I ended solving this issue with the help of some valuable hints gathered over the net and from #jeb:
Open a cmd.exe console, type ssh userC#hostC -p portC-J userB#hostB - p portB (portB and portC can be ommited if they are the default port 22) and then you will be promped to enter passwordB and passwordC - in this order.
If the connection succeeded you will be then on the hostC console and will manage to do whatever you intend to do.
The code you'll need is:
static void RunSshHop(params string[] cmds)
{
try
{
using (Process p = new Process())
{
p.StartInfo = new ProcessStartInfo("cmd.exe")
{
RedirectStandardInput = true,
UseShellExecute = false,
//WorkingDirectory = #"d:\" // dir of your "cmd.exe"
};
p.OutputDataReceived += p_DataReceived;
p.ErrorDataReceived += p_DataReceived;
p.Start();
// way 1: works
foreach (var e in cmds)
p.StandardInput.Write($"{e}\n"); // cannot use 'WriteLine' because Windows is '\r' and Linux is '\n'
/* way 2: works as well
using (var sw = p.StandardInput)
{
foreach (var e in cmds)
if (sw.BaseStream.CanWrite)
sw.Write($"{e}\n"); // cannot use 'WriteLine' because Windows is '\r' and Linux is '\n'
}
//*/
p.WaitForExit();
if (p.HasExited)
{
Console.WriteLine($"ExitCode: {p.ExitCode}");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
And you can call it like this:
static void Main(string[] args)
{
RunSshHop(
"ssh userC#hostC -p portC-J userB#hostB - p portB",
"pwd",
//"...",
"ls"
);
}
To avoid having to enter the passwords for each host, you can also create an SSH key pair like this:
open cmd.exe console
type ssh-keygen -t rsa
choose path where to save the public and private keys that are to be generated (press enter to use the default destination)
copy the destination, you will need it later to get back yxour keys :-)
to manage an automated process, you have to leave the passphrase empty
-once the keys are generated, log onto the first host over ssh like ssh youruser#firsthost -p hostport (the -p hostport part can be ignored if port is the default 22)
type ssh-copy-id youruser#firsthost -p hostport
accept
repeat the process for the second host

Connecting the SignalR console client to the server on Azure

I want to deploy a server (on Azure) using SignalR.
And the console client, so that it accepts commands from the server.
The server code was taken from here: https://learn.microsoft.com/ru-ru/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr
Example of a console client from here:https://www.codeproject.com/Articles/804770/Implementing-SignalR-in-Desktop-Applications
using Microsoft.AspNet.SignalR.Client;
using System;
namespace SignalRClient
{
class Program
{
static void Main(string[] args)
{
IHubProxy _hub;
string url = #"https://signalrchatmsdn20210410135946.azurewebsites.net/";
//string url = #"http://localhost:62545";
var connection = new HubConnection(url);
_hub = connection.CreateHubProxy("BetHub");
connection.Start().Wait();
_hub.On("ReceiveLength", x => Console.WriteLine(x));
string line = null;
while ((line = System.Console.ReadLine()) != null)
{
_hub.Invoke("DetermineLength", line).Wait();
}
Console.Read();
}
}
}
If I run the server locally, everything works (string url = #"http://localhost:62545";)
If I run the server on Azure, it works through the browser. But the console client throws an exception.
System.Net.WebException
jdweng absolutely right.
In my case, it was enough to change the deployment setting.
TLS\SSL settings => HTTPS Only: Off

How to disable soReusePort in gRPC C# Channel?

I'm trying to build a load test application for a Grpc server. I would like the channels to open different ports whenever trying to connect to the server with disabling "SoResuePort Channel Option". By using the following code:
string Host = "192.168.1.20";
int Port = 7081;
IEnumerable<ChannelOption> options = new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) };
ChannelOne = new Channel(Host, Port, ChannelCredentials.Insecure , options);
ChannelTwo = new Channel(Host, Port, ChannelCredentials.Insecure , options);
await ChannelOne.ConnectAsync();
await ChannelTwo.ConnectAsync();
I expect gRPC to open a new TCP connection per channel, but it's reusing the same TCP connection.

Error 10049 while connecting bluetooth device with 32feet

I'm trying to establish a connection with a custom bluetooth device without using COM ports. However, I'm getting an error: [10049] "The requested address is not valid in its context". What am I doing wrong?
static Guid serviceClass= new Guid("4d36e978-e325-11ce-bfc1-08002be10318"); //GUID of device class
static BluetoothAddress addr = BluetoothAddress.Parse("001210160177"); //from device
BluetoothDeviceInfo device = new BluetoothDeviceInfo(addr);
device.SetServiceState(serviceClass, true);
Console.WriteLine(BluetoothSecurity.PairRequest(device.DeviceAddress, "0000")); //pairing my device - writes True
BluetoothEndPoint ep = new BluetoothEndPoint(addr, serviceClass);
BluetoothClient conn = new BluetoothClient(ep); //10049 error
conn.Connect(ep);
Console.WriteLine(conn.GetStream());
Its all covered in the project's documentation. :-)
In short, remove that SetServiceState line it is unnecessary/bad. Doing the pairing each time is also unnecessary and a bit slow but probably not worth changing if its working well.
Docs:
1) http://32feet.codeplex.com/documentation
"See section General Bluetooth Data Connections below. The BluetoothClient provides the Stream to read and write on -- there is no need to use virtual COM ports"
2) http://32feet.codeplex.com/wikipage?title=General%20Bluetooth%20Data%20Connections
BluetoothAddress addr
= BluetoothAddress.Parse("001122334455");
Guid serviceClass;
serviceClass = BluetoothService.SerialPort;
// - or - etc
// serviceClass = MyConsts.MyServiceUuid
//
var ep = new BluetoothEndPoint(addr, serviceClass);
var cli = new BluetoothClient();
cli.Connect(ep);
Stream peerStream = cli.GetStream();
peerStream.Write/Read ...
3) http://32feet.codeplex.com/wikipage?title=Errors
10049 "The requested address is not valid in its context."
No Service with given Service Class Id is running on the remote device
i.e. Wrong Service Class Id.
Here's how it finally rolls.
device.SetServiceState(serviceClass, true); //do it before pairing
...
BluetoothClient conn = new BluetoothClient();
conn.Connect(ep);
Also, my mistake here:
static Guid serviceClass = new Guid("4d36e978-e325-11ce-bfc1-08002be10318");
//GUID of device class
Should be:
static Guid serviceClass = new Guid("00001101-0000-1000-8000-00805f9b34fb");
//GUID of bluetooth service
For seeing the proper GUID, refer to your device's (not dongle's) settings/properties. You can see them from Windows.

Windows 8 app how to connect to Socket server

i have done a server using this example socketAsyncEventArgs
in visual studio 2010 and .net 4.0.
Now i'm trying to connect to it from a windows 8 app using StreamSocket but i'm getting a "Acces denied" message.
here is the Client code:
private StreamSocket streamSocket;
public string Server = "192.168.0.101";
public int Port = 9900;
public async void Connect()
{
streamSocket = new StreamSocket();
Connect();
try
{
await streamSocket.ConnectAsync(
new Windows.Networking.HostName(Server),
Port.ToString()); // getting Acces Denied here
DataReader reader = new DataReader(streamSocket.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
while (true)
{
var bytesAvailable = await reader.LoadAsync(1000);
var byteArray = new byte[bytesAvailable];
reader.ReadBytes(byteArray);
}
}
catch (Exception e)
{
MessageBox(e.StackTrace);
}
}
How to fix the problem? Is there another way to send and receive messages using this server?
You are probably also seeing the following as part of your error message:
WinRT information: A network capability is required to access this network resource
This is because you need to add a capability to your application that allows you to access local networks. Double click on the Package.appxmanifest file in your project. Click on the Capabilities tab. Add the Private Networks (Client & Server) capability to your project.

Categories