Windows UWP StreamSocket ReOpen - c#

Hey, I have a Problem with the Windows 10 UWP API.
I'm developing a Windows 10 UWP App and need to connect to a Chromecast. I'm using SharpCaster for this. But when I open a connection to a Chromecast and close it again later on, it is not possible to connect to a Chromecast again. The socket to the Chromecast opens again, but when trying to write to it, I get the following exception:
A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)
This even happens when I turn the Chromecast off while disconnected. I disconnect the Chromecast with this Method:
public void Disconnect()
{
_running = false;
_socket.InputStream.Dispose();
_socket.OutputStream.Dispose();
_socket.Dispose();
}
The method is not found in the Library, I have written it myself. Setting _running to false stops all the loops for pinging, etc...
The socket is created with this code:
_socket = new StreamSocket().ConfigureForChromecast();
await _socket.ConnectAsync(new HostName(uri.Host), ChromecastPort, SocketProtectionLevel.Tls10);
The extension ConfigureForChromecast() looks like this:
public static StreamSocket ConfigureForChromecast(this StreamSocket socket)
{
//Chromecast is not using trusted certificate so ignoring errors caused by that
socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
socket.Control.OutboundBufferSizeInBytes = 2048;
socket.Control.KeepAlive = true;
socket.Control.QualityOfService = SocketQualityOfService.LowLatency;
return socket;
}
Finally, the messages are written to the socket with
internal async Task Write(byte[] bytes)
{
try
{
var buffer = CryptographicBuffer.CreateFromByteArray(bytes);
await _socket.OutputStream.WriteAsync(buffer);
}
catch (Exception e)
{
Debugger.Break();
}
}
And that is the point where the exception occurs. When connecting the first time, it works perfectly, but to connect a second time, I have to restart the whole app. Any ideas why?

Related

Autoconnect with Microsoft Display Adapter using Windows.Devices.WiFiDirect

First, I have extensively read through Autoconnect to MS Wireless display on Windows 10 and tried basically every solution. (I did technically get the AutoHotKey solution working, and in fact did that before even researching. But, I feel like that's kind of unprofessional and surely there is some API that can connect to this thing.) After going through all of this, I just started reading through the different namespaces. Finally, I found Windows.Devices.WiFiDirect. This gave me the most progress I've been able to get, which is, it begins to connect and says so on screen, then an exception stating that the device is unreachable occurs. Very infuriating.
Can anyone explain exactly what is happening here? It seems like this should be the proper way to connect my screen to this device, but it is just not working. Code below, it's pretty short and straightforward.
Edit:
Based on Roy Li's suggestion, I attempted to use a different overload of the socket.ConnectAsync method. This actually did have an effect but I am still receiving an exception, although a different one. The method now attempts to connect for longer but still fails out, this time with 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" exception. Could this mean there is some sort of secret handshake that Window's OS is using when connecting to this device? If so, this might be a dead end. The code has been updated below.
static async Task Main()
{
string id = null;
string prefix = "MicrosoftDisplayAdapter";
WiFiDirectDevice device;
StreamSocket socket = new StreamSocket();
try
{
DeviceInformationCollection devInfoCollection = await DeviceInformation.FindAllAsync(WiFiDirectDevice.GetDeviceSelector());
foreach (DeviceInformation devInfo in devInfoCollection)
{
if (devInfo.Name.StartsWith(prefix))
{
id = devInfo.Id;
}
}
device = await WiFiDirectDevice.FromIdAsync(id);
var endpointPairCollection = device.GetConnectionEndpointPairs();
await socket.ConnectAsync(endpointPairCollection[0].RemoteHostName, "50001"); //This line begins connecting to the display but ultimately fails
}
catch (Exception e)
{
//device unreachable exception
}
}
I finally found something along the lines of what I need. I came across https://social.msdn.microsoft.com/Forums/en-US/7608d127-d864-436a-802e-472fd55cc02c/use-projectionmanager-from-net-framework?forum=csharpgeneral, which gave me a way to cast/project to the Microsoft Display Adapter. As the link states, I do get a "Catastrophic Error" but it does make the connection and keep it, anyway. What my code ended up looking like is below:
static async Task Main()
{
string prefix = "MicrosoftDisplayAdapter";
DeviceInformation displayAdapter = null;
try
{
//Get projection devices
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(ProjectionManager.GetDeviceSelector());
foreach (DeviceInformation device in devices)
{
if (device.Name.StartsWith(prefix))
{
displayAdapter = device;
}
}
//Start projection. This throws an error but works without issue.
await ProjectionManager.StartProjectingAsync(0, 0, displayAdapter);
}
catch (Exception e)
{
//Ignore this error
if (e.Message.StartsWith("Catastrophic"))
{
//Change display to use secondary only
Process proc = new Process();
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = #"C:\Windows\Sysnative\DisplaySwitch.exe";
proc.StartInfo.Arguments = "/external";
proc.Start();
proc.WaitForExit();
}
else
{
Console.WriteLine(e);
}
}
}

How to set a custom connection timeout in 32feet

I am developing code in C# to communicate with a custom Bluetooth device. The code I use to connect to the device essentially looks like this:
BluetoothDeviceInfo device_info = new BluetoothDeviceInfo(BluetoothAddress.Parse(address_str));
try
{
BluetoothClient connection = new BluetoothClient();
connection.Connect(device_info.DeviceAddress, BluetoothService.SerialPort);
if (connection.Connected)
{
...
}
else
{
...
}
}
catch (Exception e)
{
...
}
The problem is that the Connect call often times out after about 5s. Sometimes it succeeds after about 3s and I have reason to believe that a connection could be established successfully if I allowed more time. However, I have nowhere set this timeout of 5s. I just call the Connect method and it times out at some point.
Is there a way to configure this timeout somewhere in 32feet?

StreamSocket.ConnectAsync throws Exception "HRESULT: 0x8007274C" while using a VPN

the problem: While not using a VPN, the code below works fine. As soon as I connect to my home network via a VPN the, code throws an exception (translated from german):
A connection attempt failed because the connected party did not properly respond after a certain period of time, or established connection failed because connected host has failed to respond. (Exception from HRESULT: 0x8007274C).
The target "192.168.180.58" is an another computer within my home network.
Windows Store test code:
private async void createConnection(object sender, RoutedEventArgs e)
{
HostName target = new HostName("192.168.180.58");
string port = "8181";
using (StreamSocket client = new StreamSocket())
{
try
{
await client.ConnectAsync(target, port);
}
catch (Exception ex)
{
string typeName = ex.GetType().Name;
string msg = ex.Message;
}
}
}
I created a Windows Console Program (.NET 4.5.1) that is working in both situations (connected by using vpn and not using a vpn).
Windows Console test code:
namespace caPing
{
class Program
{
static void Main(string[] args)
{
string target = "192.168.180.58";
int port = 8181;
TcpClient client = new TcpClient();
try
{
client.Connect(target, port);
client.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
}
}
It looks like that the problem is somehow related to the execution environment for Windows Store Apps (when using a vpn).
What is the problem here and how can I solve it?
Kind regards,
Sörnt
I was facing the same problem then i found that
We can not keep two app running at the same time.
If Server app is running and then run the client app, the server app will
suspend and the client app will fail with connect.
You can create a server application as a desktop app, so that the client and
server can run at the same time.
From MSDN Here.

C# Modbus/tcp - hanging connection

I have written Windows service, which perform Modbus WriteMultipleRegisters function call over TCP using NModbus library to 3-party devices every 10 minutes (ticks of System.Threading.Timer).
Occasionally this connection hang up open usually during network problems. As the device accepts only one Modbus connection at time and others are refused, connection during all next ticks fail with SocketException - ConnectionRefused.
But the device automatically closes connections which don't respond after short time. Something must keep connection open at my side even for two days. What's more when my Service is restarted, everything is fine again. So there is definitely some forgotten open connection. But I didn't manage to reproduce this bug in dev, so I don't where/when.. connection hang up. I only know that next connection is refused.
I do the modbus function call with this part of code:
using (TcpClient client = new TcpClient(device.ip, 502))
{
using (Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(client))
{
master.WriteMultipleRegisters(500, new ushort[] { 0xFF80 });
}
}
device.ip is string containing IP address of device - it's correct, confirmed from SocketException details.
As I'm using using statement dispose is called on both objects.
I have looked trough NModbus source code and everything is disposed correctly.
Any idea how its possible that with this code connection is not closed?
I agree with nemec. If you review the documentation for TcpClient.Dispose if does not specifically mention closing the connection. It frees managed and unmanaged resources by default, but it may not correctly tear down the connection.
Try changing your code to:
using (TcpClient client = new TcpClient(device.ip, 502))
{
try
{
using (Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(client))
{
master.WriteMultipleRegisters(500, new ushort[] { 0xFF80 });
}
}
catch(Exception e)
{
// Log exception
}
finally
{
client.Close();
}
}
That way you are doing a clean close before dispose and it should clean up even if the Modbus protocol throws some kind of exception.
did you play with TcpClient.LingerState Property
defualt setting could cause problems with resetting winsock
check it out
http://msdn.microsoft.com/pl-pl/library/system.net.sockets.tcpclient.lingerstate%28v=vs.110%29.aspx
This is not an answer, but a comment with code. We have this same issue on some of our installed computers, but not all of them. The issue itself is also very intermittent, sometimes going months without happening. I am hoping someone can find an answer. Here is our brute force destroy / reconnect code that does not work:
try
{
try
{
try
{
// Close the stream
var stream = _tcpClient.GetStream();
if (stream != null)
stream.Close();
}
catch { }
try
{
// Close the socket
if (_tcpClient.Client != null)
_tcpClient.Client.Close();
}
catch { }
// Close the client
_tcpClient.Close();
_tcpClient = null;
}
catch { }
if (_device != null)
{
_device.Dispose();
_device = null;
}
}
catch { }
System.Threading.Thread.Sleep(1000);

How to (really) cancel a ConnectAsync request on Windows Phone?

I'm developing a Windows Phone application that will connect to my server. It does this by using ConnectAsync when you push the login button. But if the server is down and you want to cancel the connecting attempt, what to do?
Here is is the current client code complete with my latest try at shutting the socket connection down. It is to be assumed that you can easily implement a timeout once you know how to turn the connection off.
private IPAddress ServerAddress = new IPAddress(0xff00ff00); //Censored my IP
private int ServerPort = 13000;
private Socket CurrentSocket;
private SocketAsyncEventArgs CurrentSocketEventArgs;
private bool Connecting = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
if (Connecting)
{
CurrentSocket.Close();
CurrentSocket.Dispose();
CurrentSocketEventArgs.Dispose();
CurrentSocket = null;
CurrentSocketEventArgs = null;
}
UserData userdata = new UserData();
userdata.Username = usernameBox.Text;
userdata.Password = passwordBox.Password;
Connecting = ConnectToServer(userdata);
}
catch (Exception exception)
{
Dispatcher.BeginInvoke(() => MessageBox.Show("Error: " + exception.Message));
}
}
private bool ConnectToServer(UserData userdata)
{
CurrentSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Create a new SocketAsyncEventArgs
CurrentSocketEventArgs = new SocketAsyncEventArgs();
CurrentSocketEventArgs.RemoteEndPoint = new IPEndPoint(ServerAddress, ServerPort);
CurrentSocketEventArgs.Completed += ConnectionCompleted;
CurrentSocketEventArgs.UserToken = userdata;
CurrentSocketEventArgs.SetBuffer(new byte[1024], 0, 1024);
CurrentSocket.ConnectAsync(CurrentSocketEventArgs);
return true;
}
Edit: A thought that struck me is that perhaps it's the server computer that stacks up on requests even though the server software isn't on? Is that possible?
I believe
socket.Close()
should cancel the async connection attempt. There may be some exceptions that need to be caught as a consequence.
Your code looks OK.
As already said by Marc, closing the socket cancels all pending operations.
Yes, it's sometimes possible that you connect OK and nothing happens. To verify, in the command line
telnet 192.168.1.44 31337 where 192.168.1.44 is ServerAddress (name is OK as well) and 31337 is ServerPort. You might first enable a "Telnet client" using Control Panel/Programs and Features/Turn Windows features on and off. If you see "Could not open connection" = your WinForms application shouldn't be able to connect. If you see a black screen with blinking cursor = your WinForms application should connect OK.
What's going on here is that you are specifying a buffer in the argument to ConnectAsync.
CurrentSocketEventArgs.SetBuffer(new byte[1024], 0, 1024);
The documentation says:
Optionally, a buffer may be provided which will atomically be sent on the socket after the ConnectAsync method succeeds.
So your server is going to see the connection and data at once. Your cancellation code is just fine, it's just that the data is sent before you get a chance to cancel anything.

Categories

Resources