I've read a few sources on this. I followed this accepted answer and am using Managed WiFi API to get the SSID if I am connected via WiFi. Here is my code:
private void setSSID() {
WlanClient wlan = new WlanClient();
Collection<String> connectedSsids = new Collection<string>();
foreach (WlanClient.WlanInterface wlanInterface in wlan.Interfaces) {
Wlan.Dot11Ssid ssid = wlanInterface.CurrentConnection.wlanAssociationAttributes.dot11Ssid;
connectedSsids.Add(new String(Encoding.ASCII.GetChars(ssid.SSID, 0, (int)ssid.SSIDLength)));
}
}
This will get the SSID perfectly if I am connected via WiFi but throws an exception if only connected via Ethernet. The ideal solution:
Enter setSSID() (or something to similar effect)
Check if connected via Ethernet
If so, return null/0/undefined
Else, return the SSID (I have already got a check in if it's even connected to the network or not)
I have looked all over the WMI and the NetworkInformation namespace but neither provide what I am looking for.Looking in WlanApi.cs, the exception is thrown here:
public Wlan.WlanConnectionAttributes CurrentConnection {
get {
int valueSize;
IntPtr valuePtr;
Wlan.WlanOpcodeValueType opcodeValueType;
Wlan.ThrowIfError(
Wlan.WlanQueryInterface(client.clientHandle, info.interfaceGuid, Wlan.WlanIntfOpcode.CurrentConnection, IntPtr.Zero, out valueSize, out valuePtr, out opcodeValueType));
try {
return (Wlan.WlanConnectionAttributes)Marshal.PtrToStructure(valuePtr, typeof(Wlan.WlanConnectionAttributes));
}
finally {
Wlan.WlanFreeMemory(valuePtr);
}
}
}
Also looked at:
Check whether connected to a Wi-Fi network or not C#
You can catch the exception (which you report as Win32Exception), and treat that as the "no WiFi is available" condition.
If you like, you can check the ErrorCode or HResult properties for the exception to make sure it's the error you were expecting in the case of the lack of WiFi, rather than some other more problematic exception. In the latter case, you would probably want to rethrow the exception (at least until you have decided on a good strategy for handling that type of error).
There is also the native wireless LAN API which you could use directly, handling the error codes/results from that instead of dealing with exceptions. But I think in your case, handling the exception that's thrown is simplest, since it otherwise is working just as you want.
Related
I am sending a message to a server through HTTP 1.1. Everything sends correctly to the server or website I have chosen, but when I receive the response from the server/website and my sr.readToEnd() executes, it terminates.
I know that the message I have sent is correct, but I am trying to do a try-catch statement were if it terminates again, it will try to read another way. I am not sure how to do this and I was advised that I could use content-length (except I do not know how to do that either).
Here is what I have so far:
try
{ //Read server message
String response = sr.ReadToEnd();
}
catch
{ //If terminate occurs, read a different way
}
If I remove the try/catch blocks I see this:
Unhandled Exception: System.IO.IOException: Unable to read data from the transport connection: 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.
---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time..
I know it's pretty brief what I provided, but any methods to tackle this sort of problem I described?
I'd say in general you can do (as #joel recommended.
Or try whether catch when() works for you.
Example:
try
{
someCode();
}
catch (YourExpectedException ex) when (
someBooleanExpression
|| someOtherBooleanExpr
|| thirdBoolean)
{
/* this part runs when() YourExpectedException occurs *and*
one of those three hypothetical example expressions is True */
}
catch (YourExpectedException ex)
{
/* this part runs If YourExpectedException occurs and the previous
When() expression is *Not true */
Whatever();
} /* you can continue catching other expected exceptions
and when() combinations here.
And/Or perhaps say any other exception is unexpected and
will be handled by a higher-level:
*/
catch // any other Exception just to re-throw it back 'to-whom-it-may-concern':
throw;
See also Catching exceptions with "catch, when"
I'm starting a Wi-Fi Direct access point service using the UWP APIs. It starts OK. I'm using WiFiDirectConnectionListener to monitor for devices that get connected to the access point using the ConnectionRequested event.
var connectionRequest = args.GetConnectionRequest();
var deviceInformation = connectionRequest.DeviceInformation;
// FromIdAsync needs to be called from the UI thread (in MS example).
var isConnected = RunOnUIThreadAsync(() =>
{
try
{
var device = WiFiDirectDevice.FromIdAsync(deviceInformation.Id).AsTask().Result;
if (device != null)
{
device.ConnectionStatusChanged -= OnDeviceConnectionStatusChanged;
device.ConnectionStatusChanged += OnDeviceConnectionStatusChanged;
return true;
}
return false;
}
catch (Exception e)
{
// This throws an Exception from HRESULT: 0x800705B4.
return false;
}
}).Result;
On some devices that get connected to the access point, an exception is thrown on calling FromIdAsync with
This operation returned because the timeout period expired. (Exception from HRESULT: 0x800705B4).
In turn, the device that tries to the access point will not connect.
It's always the same devices that are unable to connect, while others connect just fine. I've tried with and without UI thread but the result remains the same. Am I using this wrong, or is this a bug in Wi-Fi Direct? If so, is there another way to start a Wi-Fi Direct access point without the UWP APIs? Perhaps that's working better.
The workaround to prevent timeout is to have DHCP activated on the client side. I have had this error when trying to connect devices with fixed IP address to the hotspot.
I'm getting a very strange exception using a UWP StreamSocket, 99.9% of the time this code functions as expected and the communication with the device works properly, however I get the following exception every once in a while.
The exception message:
The operation failed because an invalid combination of workqueue ID and flags was specified. (Exception from HRESULT: 0xC00D36FF)
Sample code for the issue:
using (StreamSocket analyzerSocket = new StreamSocket())
{
HostName hostName = new HostName(host);
// Set NoDelay to false so that the Nagle algorithm is not disabled
analyzerSocket.Control.NoDelay = false;
try
{
// Connect to the server
await analyzerSocket.ConnectAsync(hostName, port.ToString()).AsTask(new CancellationTokenSource(_timeout).Token);
}
catch (Exception e)
{
var x = e;
}
}
Screenshot of exception in code:
The Stack Trace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Analyzer.<SendMessageAsync>d__120.MoveNext() in zzz.cs:line 779
I've tried my GoogleFu and I was able to find issues with MediaPlayer or Linux kernels but nothing seemed to relate to this issue with StreamSockets.
While I can trap this error and work around the issue I would like to know what's going on in case it's a symptom of a bigger issue.
Thanks in advance.
Edit 1
I thought this might be related to http://referencesource.microsoft.com/#mscorlib/system/runtime/compilerservices/TaskAwaiter.cs,be57b6bc41e5c7e4 based on the code comment of "// And throw an exception if the task is faulted or canceled.".
However I still get this expcetion when I am not using the ".AsTask(new CancellationTokenSource(timeout.Value).Token)"
Edit 2
When I have this in a loop, to constantly send messages to our device, the messages are being received until this exception occurs. Once the exception occurs and I tell it to continue and try again, the exception re-occurs over and over in the loop and the device stops receiving messages.
Edit 3
So I've tried the following, to connect to a different device, with a different instance of the StreamSocket object... and it generates the same error!
using (StreamSocket analyzerSocket = new StreamSocket())
{
HostName hostName = new HostName(host);
// Set NoDelay to false so that the Nagle algorithm is not disabled
analyzerSocket.Control.NoDelay = false;
try
{
// Connect to the server
await analyzerSocket.ConnectAsync(hostName, port.ToString()).AsTask(new CancellationTokenSource(_timeout).Token);
}
catch (Exception e)
{
using (StreamSocket analyzerSocket2 = new StreamSocket())
{
HostName hostName2 = new HostName("xxx.xxx.xxx.xxx");
// Set NoDelay to false so that the Nagle algorithm is not disabled
analyzerSocket.Control.NoDelay = false;
// Connect to the server
await analyzerSocket2.ConnectAsync(hostName2, port.ToString());
}
throw;
}
}
It feels like some sort of cross threading type of issue... I'm grasping at straws right now as I cannot trap and bypass the error as once the error occurs I can no longer talk to the devices and I must exit the application to get it to work again.
Does anyone have any other ideas or confirmation that it looks like cross threading type of issue?
Thanks in advance.
The only way I have found to prevent this issue is to stop using the "StreamSocket" altogether.
I switched my code to use the "System.Net.Sockets" namespace using the Socket object instead and with some modifications to my code I haven't encountered this issue since.
Code sample:
https://msdn.microsoft.com/en-us/library/windows/apps/hh202858%28v=vs.105%29.aspx?f=255&MSPPError=-2147217396
My application is working as a client application for a bank server. The application is sending a request and getting a response from the bank. This application is normally working fine, but sometimes
The I/O operation has been aborted because of either a thread exit or
an application request
error with error code as 995 comes through.
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived",
ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.thisSocket.EndReceive(asyn); //Here error is coming
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
}
}
Once this error starts to come for all transactions after that same error begin to appear, so
please help me to sort out this problem. If possible then with some sample code
Regards,
Ashish Khandelwal
995 is an error reported by the IO Completion Port. The error comes since you try to continue read from the socket when it has most likely been closed.
Receiving 0 bytes from EndRecieve means that the socket has been closed, as does most exceptions that EndRecieve will throw.
You need to start dealing with those situations.
Never ever ignore exceptions, they are thrown for a reason.
Update
There is nothing that says that the server does anything wrong. A connection can be lost for a lot of reasons such as idle connection being closed by a switch/router/firewall, shaky network, bad cables etc.
What I'm saying is that you MUST handle disconnections. The proper way of doing so is to dispose the socket and try to connect a new one at certain intervals.
As for the receive callback a more proper way of handling it is something like this (semi pseudo code):
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived", ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket client = (SocketPacket)asyn.AsyncState;
int bytesReceived = client.thisSocket.EndReceive(asyn); //Here error is coming
if (bytesReceived == 0)
{
HandleDisconnect(client);
return;
}
}
catch (Exception err)
{
HandleDisconnect(client);
}
try
{
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
//do your handling here
}
catch (Exception err)
{
// Your logic threw an exception. handle it accordinhly
}
try
{
client.thisSocket.BeginRecieve(.. all parameters ..);
}
catch (Exception err)
{
HandleDisconnect(client);
}
}
the reason to why I'm using three catch blocks is simply because the logic for the middle one is different from the other two. Exceptions from BeginReceive/EndReceive usually indicates socket disconnection while exceptions from your logic should not stop the socket receiving.
In my case, the request was getting timed out. So all you need to do is to increase the time out while creating the HttpClient.
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(5);
I had the same issue with RS232 communication. The reason, is that your program executes much faster than the comport (or slow serial communication).
To fix it, I had to check if the IAsyncResult.IsCompleted==true. If not completed, then IAsyncResult.AsyncWaitHandle.WaitOne()
Like this :
Stream s = this.GetStream();
IAsyncResult ar = s.BeginWrite(data, 0, data.Length, SendAsync, state);
if (!ar.IsCompleted)
ar.AsyncWaitHandle.WaitOne();
Most of the time, ar.IsCompleted will be true.
I had this problem. I think that it was caused by the socket getting opened and no data arriving within a short time after the open. I was reading from a serial to ethernet box called a Devicemaster. I changed the Devicemaster port setting from "connect always" to "connect on data" and the problem disappeared. I have great respect for Hans Passant but I do not agree that this is an error code that you can easily solve by scrutinizing code.
In my case the issue was caused by the fact that starting from .NET 5 or 6 you must either call async methods for async stream, or sync methods for sync strem.
So that if I called FlushAsync I must have get context using GetContextAsync
What I do when it happens is Disable the COM port into the Device Manager and Enable it again.
It stop the communications with another program or thread and become free for you.
I hope this works for you. Regards.
I ran into this error while using Entity Framework Core with Azure Sql Server running in Debug mode in Visual Studio. I figured out that it is an exception, but not a problem. EF is written to handle this exception gracefully and complete the work. I had VS set to break on all exceptions, so it did. Once I unchecked the check box in VS to not break on this exception, my C# code, calling EF, using Azure Sql worked every time.
In my application, I currently stop listening when AcceptTcpClient (or EndAcceptTcpClient) throws an exception. Typically exceptions are thrown when I stop the listener (socket error 10004) or when I disconnect the network adapter.
try
{
while (true)
{
TcpClient client = listener.AcceptTcpClient();
// omitted: start new thread which handles the client connection
}
}
catch (...)
{
// omitted: handle exception, log, stop listening
}
But, are there any exceptions that are caused by the client, and would require to ignore (or log) the exception and continue calling AcceptTcpClient?
MSDN has documentation that will list all exceptions that can be thrown by methods/members/etc.
I find it easy to get where you want to go by searching google for something like "MSDN Ssystem.Net.Sockets.TcpListener class" and then navigating to the page I need.
TcpLisenter.AcceptTcpClient Method
MSDN lists 2 exceptions that can be thrown.
InvalidOperationException : The listener has not been started with a call to Start.
SocketException : Use the SocketException.ErrorCode property to obtain the specific error code. When you have obtained this code, you can refer to the Windows Sockets version 2 API error code documentation in MSDN for a detailed description of the error.