This is only the important stuff that the bluescreen shows. I'm on Windows 7 x64.
"A problem has been detected and Windows has been shut down to prevent damage
to your computer.
PROCESS_HAS_LOCKED_PAGES
* STOP: 0x00000076 (0x0000000000000000, 0xfffffa8009dcd060, 0x0000000000000011,
0x0000000000000000)"
I can't work on it now because every time I close it I get a bluescreen!
The program doesn't do anything yet except run the background worker below. It pings all addresses that could be part of the user's home network and attempts to connect to a certain port that another program will be listening on.
private void NetworkScanner_DoWork(object sender, DoWorkEventArgs e)
{
bool ExceptionEncountered = false;
int IPsProcessed = 0;
NetworkSearcherOutput = "Starting network scanner...";
NetworkSearcher.ReportProgress(0);
Thread.Sleep(1000);
foreach (IPAddress IP in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (IP.AddressFamily == AddressFamily.InterNetwork)
{
string[] Octets = IP.ToString().Split('.');
Octets[3] = "0";
IPAddress CurrentAddressIteration = StringArrayToIP(Octets);
while (GetLastOctet(CurrentAddressIteration) != 255)
{
PingReply Reply = new Ping().Send(CurrentAddressIteration, 5);
if (Reply.Status == IPStatus.Success)
{
NetworkSearcherOutput = CurrentAddressIteration.ToString() + " sent response.";
NetworkSearcher.ReportProgress(0);
Thread.Sleep(500);
InClient Client = new InClient(CurrentAddressIteration);
try
{
Client.Connect();
SnapshotBox.Image = Client.Receive(typeof(Image));
NetworkSearcherOutput = CurrentAddressIteration.ToString() + " is running program.";
NetworkSearcher.ReportProgress(0);
Thread.Sleep(1000);
}
catch (Exception E)
{
// A socket exception is expected when the client is not running the program.
if (E is SocketException)
{
Client.Close();
NetworkSearcherOutput = CurrentAddressIteration.ToString() + " is not running program.";
NetworkSearcher.ReportProgress(0);
Thread.Sleep(1000);
}
//Unhandled exception. Show messagebox and close.
else
{
MessageBox.Show("Network scanner encountered an unhandled exception.\n\n" + E.GetType().ToString() + ": " + E.Message, "Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
ExceptionEncountered = true;
break;
}
}
}
else
{
NetworkSearcherOutput = CurrentAddressIteration.ToString() + " did not respond.";
NetworkSearcher.ReportProgress(0);
}
IPsProcessed++;
if (IPsProcessed == 5)
{
NetworkSearcher.ReportProgress(2);
IPsProcessed = 0;
}
Octets = CurrentAddressIteration.ToString().Split('.');
Octets[3] = (Int32.Parse(Octets[3]) + 1).ToString();
CurrentAddressIteration = StringArrayToIP(Octets);
}
}
}
if (!ExceptionEncountered)
{
NetworkSearcherOutput = "Network scanning complete.";
NetworkSearcher.ReportProgress(0);
NetworkSearcher.ReportProgress(100);
}
else
{
NetworkSearcherOutput = "Network scanning encountered an error.";
NetworkSearcher.ReportProgress(-1);
}
I thought C# programs were supposed to never cause bluescreens?
I discovered this issue a few weeks back. It only happens when using .NET 4.
Reported at MS Connect.
Edit:
(Will*) Add this link to MS Connect bug report.
*login.live.com is going into an infinite loop again...
Just to be clear, there is no way for "user" mode code to forcibly create a blue screen in windows, unless it uses undocumented APIs and or forces bad data into a driver. Your C# code is likely not be at fault here, as if you use the user mode classes (Socket) then the socket is responsible for not crashing your computer.
As #Joe has commented Microsoft Support KB Article 256010 clearly describes this stop message, but better yet has clear instructions on capturing the driver name responsible for this error.
Note that any software firewall that you have installed also is involved at kernel mode level so could also be responsible for this error. I recommend you follow the KB articles advice and try to find out what is at fault. But you could also ensure that you have updated your network drivers and firewall/VPN software to the latest stable versions.
Related
As a workaround for a dumb issue, I have a separate application do my SharePoint file syncing that I launch as a separate process and communicate via WriteLine and ReadLine. After the third Sync command, it seems the Process executes it (as evidenced by a separate log file), but my SyncToolMessageHandler is no longer getting alerted to its responses even with forced flushes on the external process. If I run the program myself and send the exact same commands, no issue in the console window. So why do I seem to lose my message handler? The Process handle is still alive and well.
I also see this in my debugger on SyncToolProcess. It shows this before I send the first WriteLine so I'm not sure what it's talking about but maybe it's a clue? I'm establishing the process/callbacks and sending commands from an "Update" loop in Unity and the responses are obviously asynchronous whenever the process responds. Is that somehow a problem?
Sender:
public void LaunchSyncTool()
{
SyncToolProcess = new Process();
SyncToolProcess.StartInfo.FileName = "SyncProcess.exe";
SyncToolProcess.StartInfo.Arguments = SpecialArguments;
SyncToolProcess.StartInfo.UseShellExecute = false;
SyncToolProcess.StartInfo.RedirectStandardOutput = true;
SyncToolProcess.StartInfo.RedirectStandardInput = true;
SyncToolProcess.StartInfo.RedirectStandardError = true;
SyncToolProcess.StartInfo.CreateNoWindow = true;
SyncToolProcess.OutputDataReceived += new DataReceivedEventHandler(SyncToolMessageHandler);
SyncToolProcess.ErrorDataReceived += new DataReceivedEventHandler(SyncToolMessageHandler);
SyncToolProcess.Start();
SyncToolProcess.BeginOutputReadLine();
SyncToolProcess.BeginErrorReadLine();
SyncToolProcess.StandardInput.WriteLine("Sync File1 File2");
}
// Super simplified, but the ping and pong works great until about the 3rd sync.
public void SyncToolMessageHandler(object sender, DataReceivedEventArgs e)
{
if (e.Data == "Good")
{
Debug("Received 'Good', Sending Command");
SyncToolProcess.StandardInput.WriteLine("Sync File3 File4");
}
else Debug(e.Data); // Exceptions come up Null for some reason, but not seeing them here :-\
// SyncToolProcess.HasExited is always false
}
Receiver:
while (true)
{
string inputCmd = await Console.In.ReadLineAsync();
Debug("Received \"" + inputCmd + "\"");
try
{
string[] split = inputCmd.Split(' ');
switch (split[0])
{
case "Sync":
Sync(split);
break;
case "Quit":
Debug("Quitting");
return;
default:
Debug("Unknown Request: " + inputCmd);
break;
}
}
catch (Exception e)
{
Error(e.Message + "\n" + e.StackTrace);
}
Status("Good");
}
Ugh. The problem was the Unity Editor. If I build the program first it no longer misses the callbacks. Not exactly an answer for using the Editor, but at least I know the code is right!
I am using my RaspberryPis (v3) running the latest stable Windows IoT Core version (v.10.0.17763.737) to retrieve data and control my bluetooth thermostats. I am struggling quite a long time with the stability of the bluetooth connection. Some months ago I switched all my nodes to external dongles (one from the microsoft compatibility list: ORICO BTA-403), which improved the situation, but it is still far away from being stable.
After a certain time (varies from minutes to days) the bluetooth connection stops working. I already implemented a powershell script to check for such situations and fire a "devcon restart USB" command. This helps, but only in about 50% of all failures. If it does not solve the situation, I have to reboot the node. However, this is not satisfying, because from time to time the nodes freeze while booting and I made the experience that doing too many reboots will reduce the lifetime of the micro sd card.
After some hours of analysis I found out that the bluetooth support service could be the problem. Before the connection crashes I can easily restart the bluetooth support service using powershell. After the problem occured, this is not possible anymore. The service restart hangs up and the status of the service says it is pending for restart or something like this.
Do you guys made the same experience? Or is my bluetooth connection implementation too bad? I attached the function for you to have a look:
private async Task Connect()
{
try
{
int count = 0;
do
{
count++;
if (count > 10)
{
m_IsInitialized = false;
//throw new Exception("More than 10 tries have not been successfull for connecting with thermostat module. Stopping.");
}
m_IsInitialized = false;
m_Device = await BluetoothLEDevice.FromIdAsync(m_DeviceID);
if (m_Device == null)
{
throw new Exception("Device was not found.");
}
m_Characteristics = new Dictionary<ushort, GattCharacteristic>();
GattDeviceServicesResult gattServices = await m_Device.GetGattServicesAsync();
foreach (GattDeviceService service in gattServices.Services)
{
try
{
GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync();
IReadOnlyList<GattCharacteristic> characteristics = characteristicsResult.Characteristics;
foreach (GattCharacteristic characteristic in characteristics)
{
try
{
m_Characteristics.Add(characteristic.AttributeHandle, characteristic);
GattCharacteristicProperties properties = characteristic.CharacteristicProperties;
if (properties.HasFlag(GattCharacteristicProperties.Notify))
{
try
{
GattCommunicationStatus status = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
if (status == GattCommunicationStatus.Success)
{
characteristic.ValueChanged += Characteristic_ValueChanged;
m_IsInitialized = true;
//Logger.ServiceLog(string.Format("Thermostat has been initialized successfully ({0} tries).", count));
return;
}
}
catch (Exception ex4)
{
throw new Exception("4: GattCommunicationStatus: " + ex4.Message + "\nStackTrace: " + ex4.StackTrace);
}
}
}
catch (Exception ex3)
{
throw new Exception("3: GattCharacteristic: " + ex3.Message + "\nStackTrace: " + ex3.StackTrace);
}
}
}
catch (Exception ex2)
{
throw new Exception("2: GattDeviceService: " + ex2.Message + "\nStackTrace: " + ex2.StackTrace);
}
}
//Logger.ServiceLog(string.Format("Thermostat:Connect: Unsuccessful try: {0}", count));
await Task.Delay(1 * 60 * 1000);
}
while (!m_IsInitialized);
}
catch (Exception ex)
{
Logger.ServiceLog("1: Thermostat.cs Connect", ex);
}
}
As you see, the code is full of debugging helps, but no exception is raised at all when the connectivity collapses. I am really looking forward to any help, because after months of struggling I would really prefer getting to a stable solution without any hacks or workarounds.
Thanks for all your help :-)
I am working on HoloLens (Unity-UWP) and trying to make a connection with PC (UWP) or Android phone work (Xamarin). So far I tried client and host with both Bluetooth and TCP (even two versions with different libraries) on Android and UWP. I kept the code entirely separated from user interface, so that it is easier to use, to understand and modular. An Action<string> is used to output results (error logs and sent messages).
Everything that is not on the HoloLens works fine (even though it's exactly the same code). It worked from PC (UWP) to Android with client and host switched. But it doesn't even work between HoloLens and PC (UWP). The behavior ranged from crashes (mostly for Bluetooth) to instant disconnection. The last tests resulted in disconnection once bytes are about to be received. It could even read the first 4 bytes (uint for the length of the following UTF-8 message), but then it was disconnected. The other devices seemed to work fine.
What I know: Capabilities are set, the code works, the issue is likely something that is common for everything that has to do with networking and HoloLens.
So the question is, is Unity or HoloLens incompatible with something I am using? What I used which is worth mentioning: StreamSocket, BinaryWriter, BinaryReader, Task (async, await). Or is HoloLens actively blocking communication with applications on other devices? I know it can connect to devices with Bluetooth and that it can connect via TCP, and it looks like people succeed to get it to work. Are there known issues? Or is there something with Unity that causes this - a bad setting maybe? Do I have to use async methods or only sync? Are there incompatibility issues with Tasks/Threads and Unity? Is this possibly the issue (inability to consent to permissions)?
Another thing to note is that I cannot ping HoloLens via its IP by using the cmd, even though the IP is correct.
I'd appreciate any advice, answer or guess. I can provide more information if requested (see also the comments below). I would suggest to focus on the TCP connection as it seemed to be working better and appears to be more "basic." Here is the code:
using System;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Windows.Networking;
using Windows.Networking.Sockets;
#region Common
public abstract class TcpCore
{
protected StreamSocket Socket;
protected BinaryWriter BWriter;
protected BinaryReader BReader;
protected Task ReadingTask;
public bool DetailedInfos { get; set; } = false;
public bool Listening { get; protected set; }
public ActionSingle<string> MessageOutput { get; protected set; } = new ActionSingle<string> (); // Used for message and debug output. They wrap an Action and allow safer use.
public ActionSingle<string> LogOutput { get; protected set; } = new ActionSingle<string> ();
protected const string USED_PORT = "1337";
protected readonly Encoding USED_ENCODING = Encoding.UTF8;
public abstract void Disconnect ();
protected void StartCommunication ()
{
Stream streamOut = Socket.OutputStream.AsStreamForWrite ();
Stream streamIn = Socket.InputStream.AsStreamForRead ();
BWriter = new BinaryWriter (streamOut); //{ AutoFlush = true };
BReader = new BinaryReader (streamIn);
LogOutput.Trigger ("Connection established.");
ReadingTask = new Task (() => StartReading ());
ReadingTask.Start ();
}
public void SendMessage (string message)
{
// There's no need to send a zero length message.
if (string.IsNullOrEmpty (message)) return;
// Make sure that the connection is still up and there is a message to send.
if (Socket == null || BWriter == null) { LogOutput.Trigger ("Cannot send message: No clients connected."); return; }
uint length = (uint) message.Length;
byte[] countBuffer = BitConverter.GetBytes (length);
byte[] buffer = USED_ENCODING.GetBytes (message);
if (DetailedInfos) LogOutput.Trigger ("Sending: " + message);
BWriter.Write (countBuffer);
BWriter.Write (buffer);
BWriter.Flush ();
}
protected void StartReading ()
{
if (DetailedInfos) LogOutput.Trigger ("Starting to listen for input.");
Listening = true;
while (Listening)
{
try
{
if (DetailedInfos) LogOutput.Trigger ("Starting a listen iteration.");
// Based on the protocol we've defined, the first uint is the size of the message. [UInt (4)] + [Message (1*n)] - The UInt describes the length of the message (=n).
uint length = BReader.ReadUInt32 ();
if (DetailedInfos) LogOutput.Trigger ("ReadLength: " + length.ToString ());
MessageOutput.Trigger ("A");
byte[] messageBuffer = BReader.ReadBytes ((int) length);
MessageOutput.Trigger ("B");
string message = USED_ENCODING.GetString (messageBuffer);
MessageOutput.Trigger ("Received Message: " + message);
}
catch (Exception e)
{
// If this is an unknown status it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus (e.HResult) == SocketErrorStatus.Unknown)
{
// Seems to occur on disconnects. Let's not throw().
Listening = false;
Disconnect ();
LogOutput.Trigger ("Unknown error occurred: " + e.Message);
break;
}
else
{
Listening = false;
Disconnect ();
break;
}
}
}
LogOutput.Trigger ("Stopped to listen for input.");
}
}
#endregion
#region Client
public class GTcpClient : TcpCore
{
public async void Connect (string target, string port = USED_PORT) // Target is IP address.
{
try
{
Socket = new StreamSocket ();
HostName serverHost = new HostName (target);
await Socket.ConnectAsync (serverHost, port);
LogOutput.Trigger ("Connection successful to: " + target + ":" + port);
StartCommunication ();
}
catch (Exception e)
{
LogOutput.Trigger ("Connection error: " + e.Message);
}
}
public override void Disconnect ()
{
Listening = false;
if (BWriter != null) { BWriter.Dispose (); BWriter.Dispose (); BWriter = null; }
if (BReader != null) { BReader.Dispose (); BReader.Dispose (); BReader = null; }
if (Socket != null) { Socket.Dispose (); Socket = null; }
if (ReadingTask != null) { ReadingTask = null; }
}
}
#endregion
#region Server
public class GTcpServer : TcpCore
{
private StreamSocketListener socketListener;
public bool AutoResponse { get; set; } = false;
public async void StartServer ()
{
try
{
//Create a StreamSocketListener to start listening for TCP connections.
socketListener = new StreamSocketListener ();
//Hook up an event handler to call when connections are received.
socketListener.ConnectionReceived += ConnectionReceived;
//Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use.
await socketListener.BindServiceNameAsync (USED_PORT);
}
catch (Exception e)
{
LogOutput.Trigger ("Connection error: " + e.Message);
}
}
private void ConnectionReceived (StreamSocketListener listener, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
listener.Dispose ();
Socket = args.Socket;
if (DetailedInfos) LogOutput.Trigger ("Connection received from: " + Socket.Information.RemoteAddress + ":" + Socket.Information.RemotePort);
StartCommunication ();
}
catch (Exception e)
{
LogOutput.Trigger ("Connection Received error: " + e.Message);
}
}
public override void Disconnect ()
{
Listening = false;
if (socketListener != null) { socketListener.Dispose (); socketListener = null; }
if (BWriter != null) { BWriter.Dispose (); BWriter.Dispose (); BWriter = null; }
if (BReader != null) { BReader.Dispose (); BReader.Dispose (); BReader = null; }
if (Socket != null) { Socket.Dispose (); Socket = null; }
if (ReadingTask != null) { ReadingTask = null; }
}
}
#endregion
Coincidentially, I just implemented a BT connection between HoloLens and an UWP app. I followed the sample at https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BluetoothRfcommChat.
As capabilities, I set "Bluetooth" (of course), "Internet (Client & Server)" and "Private Networks (Client & Server)". The steps on the server side then are:
Create an RfcommServiceProvider for your own or an existing (eg OBEX object push) service ID.
Create a StreamSocketListener and wire its ConnectionReceived Event.
Bind the service Name on the listener: listener.BindServiceNameAsync(provider.ServiceId.AsString(), SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
If you have a custom service ID, set its name along with other attributes you may want to configure. See the sample linked above for this. I think, this is mostly optional.
Start advertising the BT service: provider.StartAdvertising(listener, true);
Once a client connects, there is a StreamSocket in the StreamSocketListenerConnectionReceivedEventArgs that you can use to create a DataReader and DataWriter on like on any other stream. If you only want to allow one client, you can also stop advertising now.
On the client side, you would:
Show the DevicePicker and let the user select the peer device. Do not forget setting a filter like picker.Filter.SupportedDeviceSelectors.Add(BluetoothDevice.GetDeviceSelectorFromPairingState(true)); You can also allow unpaired devices, but you need to call PairAsync before you can continue in step 2. Also, I think there is no way to circumvent the user consent dialogue in this case, so I would recommend pairing before. To be honest, I did not check whether the unpaired stuff works on HoloLens.
You get a DeviceInformation instance from the picker, which you can use to obtain a BT device like await BluetoothDevice.FromIdAsync(info.Id);
Get the services from the device like device.GetRfcommServicesAsync(BluetoothCacheMode.Uncached); and select the one you are interested in. Note that I found that the built-in filtering did not behave as expected, so I just enumerated the result and compared the UUIDs manually. I believe that the UWP implementation performs a case-sensitive string comparison at some point, which might lead to the requested service not showing up although it is there.
Once you found your service, which I will call s from now on, create a StreamSocket and connect using socket.ConnectAsync(s.ConnectionHostName, s.ConnectionServiceName, SocketProtectionLevel.PlainSocket);
Again, you can not create the stream readers and writers like on the server side.
The answer is Threading.
For whoever may have similar issues, I found the solution. It was due to Unity itself, not HoloLens specifically. My issue was that I wrote my code separately in an own class instead of commingle it with UI code, which would have made it 1. unreadable and 2. not modular to use. So I tried a better coding approach (in my opinion). Everybody could download it and easily integrate it and have basic code for text messaging. While this was no issue for Xamarin and UWP, it was an issue for Unity itself (and there the Unity-UWP solution as well).
The receiving end of Bluetooth and TCP seemed to create an own thread (maybe even something else, but I didn't do it actively), which was unable to write on the main thread in Unity, which solely handles GameObjects (like the output log). Thus I got weird log outputs when I tested it on HoloLens.
I created a new TCP code which works for Unity but not the Unity-UWP solution, using TcpClient/TcpListener, in order to try another version with TCP connection. Luckily when I ran that in the editor it finally pointed on the issue itself: The main thread could not be accessed, which would have written into the UI - the text box for the log output. In order to solve that, I just had to use Unity's Update() method in order to set the text to the output. The variables themselves still could be accessed, but not the GameObjects.
I'm writing one of my first apps and I have ran into a issue. When input a address that's unreachable after my foreach loop exits my App enters Break Mode, however if the foreach gets result it proceeds normally.
This is part of the code that throws the exception:
private async void Button_Click(object sender, RoutedEventArgs e)
{
/// Verify that input box is not blank
if (string.IsNullOrWhiteSpace(inputBox.Text))
{
MessageBox.Show("Cannot be left blank !", "Error");
return;
}
/// Creates a list of Gateway options to try from
string[] gatewayArray = { "cadg0", "frdg0", "dedg0", "gbdg0", "iedg0", "usdg0", "dg", "dg0" };
/// Specifies where to get store number from
string storeNumber = inputBox.Text;
string pingReply;
string pingStatus;
clearButton_Click(sender, e);
Ping ping = new Ping();
foreach (string gateway in gatewayArray)
try
{
/// Replace store number with "Wait" text and changes color of box to red.
inputBox.Text = "Please Wait...";
inputBox.Background = Brushes.Red;
/// Pings selected store using Async method
PingReply reply = await ping.SendPingAsync(gateway + storeNumber, 2000);
pingReply = reply.Address.ToString();
pingStatus = reply.Status.ToString();
/// Displays results of Ping
ipOne.Clear();
ipOne.Text = pingReply;
statusOne.Clear();
statusOne.Text = pingStatus;
if (statusOne.Text == "Success")
{
statusOne.Text = "- ONLINE -";
statusOne.Background = Brushes.LightGreen;
}
else
{
statusOne.Background = Brushes.Orange;
}
/// Get name of host
IPHostEntry ipHostOne = Dns.GetHostEntry(pingReply);
string ipOneName = ipHostOne.HostName;
ipOneName = ipOneName.Substring(0, ipOneName.LastIndexOf(".") - 10);
nameOne.Text = ipOneName.ToUpper();
}
catch (ArgumentOutOfRangeException ex)
{
MessageBox.Show(ex.Message);
}
catch (PingException)
{
/// Catches exceptions and continues
/// MessageBox.Show("Unreachable !");
}
If I specify incorrect store number I get:
Exception thrown: 'System.ArgumentOutOfRangeException' in mscorlib.dll
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred
in mscorlib.dll
StartIndex cannot be less than zero.
The program '[19616] SbPinger.exe' has exited with code -1 (0xffffffff).
I tried to handle it with try / catch:
catch (ArgumentOutOfRangeException ex)
{
MessageBox.Show(ex.Message);
}
However the catch does nothing and the program still enters Break mode.
My program simply pings all possible default Gateways and returns IP if its finds one, then pings the individual PC's on that network. Everything else works except when the Ping doesn't reach any gateway. Please go easy on me as I been using C# for only couple weeks. Any help would be greatly appreciated.
Peter
So after looking around for a while and trying different things I have found that using Dns.GetHostEntry instead of pinging the URL, yields much faster results and doesn't crash out since all the processes finish. Here's the code if anyone is interested:
// Get IP from DG adrress
try
{
IPHostEntry hostEntry = Dns.GetHostEntry("URL");
IPAddress[] address = hostEntry.AddressList;
textBox.Text = address.GetValue(0).ToString();
}
catch
{
// Catches Exception and moves on
// MessageBox.Show("No result", "Error");
}
Thanks for the response !
Background : my application has the option to check automatically whether a device on the network is connected to the network.
If a device is not connected, it is represented as a blue square, and a green square for connected. I've tested the program rather thoroughly and have a few different sets of data to look at;
If a device starts off disconnected, i can connect, and then disconnect, which goes from blue, to green, to blue, but stops functioning after this.
If a device starts of connected, i can disconnect, but then not connect again, so this goes from green, to blue, but then stops functioning.
Here are some snippets of code to show how i'm connecting to these (this is not asynchronous as some devices to not have callbacks(?));
TcpClient _tc = new TcpClient();
if (!_tc.Client.Connected)
{
try
{
_tc.Client.Connect(device.deviceIPAddress, device.devicePort);
_tc.Client.ReceiveTimeout = 10;
}
catch
{
if (deviceDownNotified == false)
{
//do stuff to notify me
}
}
}
if (_tc.Client.Connected)
{
tcpSet = true;
try
{
result = this.SendCommandResult(bData, 72);
if (result[0] == 0xF0 && result[1] == 0xF0 && result[2] == 0x00 && result[3] == 0x02 && result[68] == 0xF0 && result[69] == 0xF0)
{
CheckChanges(result, device, exit);
deviceDownNotified = false;
}
}
catch
{
}
}
edit: also i was just thinking, theres not really any need for me to disconnect manually sometimes. if a client isn't connected, then connect, if it is, then do stuff. i'm a bit baffled as to which it switches between states once and stops working though.
I think my issue may be due to the way i am disconnecting the socket / client if the device is disconnected. Anyone have any ideas? if you need more information, just ask.
edit 2: i wired up a reconnect button that i clicked manually when it should reconnect and i get the following error exception:
"Once the socket has been disconnected, you can only reconnect again asynchronously, and only to a different EndPoint. BeginConnect must be called on a thread that won't exit until the operation has been completed."
fixed my own problem. finally. Here's some information for anyone out there reading this that may be looking for a solution.
from what i gather, when a TCP connection is interrupted, you must create a new one as it's not possible to reconnect or reuse in this way. what i did was this:
(modified from code in my question)
if (!_tc.Connected)
{
try
{
connect2(deviceIPAddress, devicePort);
}
catch
{
if (deviceDownNotified == false)
{
((ListBox)mainUI.Controls["lbLog"]).InvokeEx(f => ((ListBox)mainUI.Controls["lbLog"]).Items.Add("device " + device.deviceDescription + " down at " + System.DateTime.Now));
(mainUI.Controls["btn" + device.deviceButtonNumber]).BackgroundImage = null;
(mainUI.Controls["btn" + device.deviceButtonNumber]).BackColor = Color.Blue;
deviceDownNotified = true;
try
{
_tc = new TcpClient();
initialPoll = false;
MessageBox.Show("here");
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
}
}
Here i simply created a new tcplistener with the same name (my original one was a variable of an instance of a class (what a tongue twister). creating this new TCP instance and then setting my inialPoll variable allowed everything to get back into track.