My server app runs perfectly fine until I try to close it. At that point i'm getting two exceptions. I put in a try-catch to try and debug them, and go the following:
The first exception is: A blocking operation was interrupted by a call to WSACancelBlockingCall and the 2nd one is Not listening. You must call the Start() method before calling this method.
Here's a snippet from where the exception occurs:
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
try
{
TcpClient client = this.tcpListener.AcceptTcpClient(); // EXCEPTION OCCURS HERE
string clientIPAddress = "" + IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
ClientIPLabel.Text = clientIPAddress;
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString());
}
}
}
I'm not sure if it might be because I'm missing something here or not, but here's my code for closing the server app:
private void ShutdownServer_Click(object sender, EventArgs e)
{
this.tcpListener.Stop();
Application.Exit();
}
I'm also unable to run this app from a release build; it just freezes as soon as I try to run it, and I need to restart my machine in order to close it (I can close the form, but the process stays running in task manager and "end task" doesn't close it). I'm assuming these exceptions are likely what's causing that issue, since I can run the debug build just fine.
The exception is normal. It happens because you are concurrently closing a listener that is accepting at that time.
Catching that exception and throwing it away is the right choice. I would do it like this to make the catch safer:
//Stop:
isStopping = true;
this.tcpListener.Stop();
//...
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
try
{
TcpClient client = this.tcpListener.AcceptTcpClient();
//...
}
catch (Exception e)
{
if (!isStopping) throw; //don't swallow too much!
}
}
}
There is no cleaner (exception free) way to interrupt socket operations. (Yes, this is a bad situation.)
Regarding the freezing issue, this is not normal and not a .NET issue (.NET can't prevent a process from being killed, there is no such Windows API). Windows bug, OS corruption, Anti Virus, Firewall, ...
Related
I have a WinForms C# .NET 4.5.2 OWIN self hosted server that uses a signalr hub. In this same WinForm project I start the signalr hub as follows:
private void Form1_Load(object sender, EventArgs e) {
hubConnection = new HubConnection("http://localhost:12345/", clientParams);
hubProxy = hubConnection.CreateHubProxy("OfmControl");
hubProxy.On("Message", message => onData(message));
hubConnection.Start();
My onData method looks like this:
private void onData(dynamic message)
{
var file = new System.IO.FileInfo(message);
playVideo(file.FullName);
}
playVideo method looks like this:
private void playVideo(string file)
{
int tc6 = 0;
try
{
axWMPn[0].URL = file;
}
catch (System.Runtime.InteropServices.COMException comEx)
{
Console.WriteLine("playVideo COMException 0: " + comEx.Source + " -- " + comEx.Message);
}
}
axWMPn is an activex Windows Media Player object on the main form. When I run a separate C# signalr client program and send a filename message to this OWIN signalr sever and onData receives the filename and assigns it to axWMPn[0] per above code it always works never hits catch exception never receive a cross thread exception? I have run it hundreds of times never once received a cross thread exception and always works? But if I do the following I receive a cross thread exception every time obviously:
private void onData(dynamic message)
{
textBox1.text = message; ---> cross thread exception everytime here
var file = new System.IO.FileInfo(message);
playVideo(file.FullName);
}
I started thinking what I am doing is a cross thread violation but why does it always work why am I not receiving a thread violation in Visual Studio when I run the project in debug mode like I always do when I attempt to assign textBox1.text in onData? I have a feeling it has something to do with axWMP being an activex COM object but still seems I should eventually have a cross thread exception on this if it is?
If it is a cross thread violation do I need to do a BeginInvoke/Invoke around axWMPn[0] assignment?
Thanks for any advice...
My server has a 'stop' button that should disconnect the client. The issue I'm having, is the client doesn't register that it's disconnected - or maybe it isn't disconnecting altogether. When I hit the red 'X' on my server window, the client will write in the console that it's disconnected, and try to reconnect. So, why doesn't my stop button have the same effect that closing the window does?
Hopefully these snippets will give you a better understanding of the problem I'm having:
Right here is the client. As you can see, it waits for commands from the server. If the 'try' fails(the server window is closed' it knows its disconnected, and says 'client disconnected' and attempts to reconnect.
public static void waitForCommands()
{
while (client.Connected)
{
try
{
readBuffer = new byte[client.ReceiveBufferSize];
int data = stream.Read(readBuffer, 0, readBuffer.Length);
string plainText = Encoding.ASCII.GetString(readBuffer, 0, data);
if (plainText.Contains("mbox"))
{
MessageBox.Show(plainText.Split('<','>')[1]);
}
else if (plainText.Contains("process"))
{
Process.Start(plainText.Split('<', '>')[1]);
}
}
catch
{
MessageBox.Show("Client disconnected");
new Thread(attemptConnection).Start();
}
}
}
Right here is the code to my 'stop' button. It should have the same effect as closing the window(minus the part where the application closes), but it doesn't. When I click it, it causes the client to hang. It doesn't even attempt to reconnect.
private void simpleButton2_Click(object sender, EventArgs e)
{
try
{
f.labelControl1.Text = "Disconnected";
client.Client.Disconnect(true);
server.Stop();
}
catch
{
}
}
I've tried many other lines of code besides 'client.Client.Disconnect(true);' client.Close(); , client.Client.Close();, all had the same result
When a socket disconnects, the stream.Read() on the other side will return 0 - only when the server stops abrubtly, your client will at some point catch an exception.
So just add a check if data == 0 to handle a graceful disconnect. Close the stream on the client side to 'complete the circle'.
BTW you may want to distinguish catch (SocketException) from other exceptions instead of assuming "if something goes wrong, the server must have stopped".
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?
public bool Connect (string address, int remotePort)
{
if (_socket != null && _socket.Connected)
return true;
IPHostEntry hostEntry = Dns.GetHostEntry (address);
foreach (IPAddress ip in hostEntry.AddressList) {
try {
IPEndPoint ipe = new IPEndPoint (ip, remotePort);
_socket = new Socket (ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
break;
} catch (System.Exception e) {
PushPacket ((ushort)MsgIds.Id.CONNECTION_ATTEMPT_FAILED, e.Message);
return false;
}
}
return true;
}
void ConnectionCallback (System.IAsyncResult ar)
{
NetBitStream stream = new NetBitStream ();
stream._socket = (Socket)ar.AsyncState;
try {
_socket.EndConnect (ar);
_socket.SendTimeout = _sendTimeout;
_socket.ReceiveTimeout = _revTimeout;
PushPacket ((ushort)MsgIds.Id.CONNECTION_REQUEST_ACCEPTED, "");
_socket.BeginReceive (stream.BYTES, 0, NetBitStream.HEADER_LENGTH, SocketFlags.None, new System.AsyncCallback (ReceiveHeader), stream);
} catch (System.Exception e) {
if (e.GetType () == typeof(SocketException)) {
if (((SocketException)e).SocketErrorCode == SocketError.ConnectionRefused) {
PushPacket ((ushort)MsgIds.Id.CONNECTION_ATTEMPT_FAILED, e.Message);
} else
PushPacket ((ushort)MsgIds.Id.CONNECTION_LOST, e.Message);
}
Disconnect (0);
}
}
Here are two functions. When I call
client.Connect ("127.0.0.1", 10001);
It just steps over the break; after
_socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
and goes to return true;. I set a breakpoint at ConnectionCallback but it does not go into this function.
There is no server listening on the 10001 port.
So I think it at least should throw an exception (connect failed), then go into the catch.
Or have I made a mistake in the two functions?
Here is a Minimal, Complete, and Verifiable example
using System;
using System.Net.Sockets;
using System.Net;
namespace TestSocket
{
class MainClass
{
public static void Main (string[] args)
{
NetTCPClient tcp_client = new NetTCPClient ();
tcp_client.Connect ("127.0.0.1", 10001);
}
}
class NetTCPClient
{
Socket _socket = null;
public bool Connect (string address, int remote_port)
{
if (_socket != null && _socket.Connected)
return true;
IPHostEntry host_entry = Dns.GetHostEntry (address);
foreach (IPAddress ip in host_entry.AddressList) {
try {
IPEndPoint ipe = new IPEndPoint (ip, remote_port);
_socket = new Socket (ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
IAsyncResult ia = _socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
break;
} catch (Exception e) {
Console.WriteLine ("Connet() catch an exception!");
return false;
}
}
return true;
}
void ConnectionCallback (System.IAsyncResult ar)
{
Console.WriteLine ("ConnectionCallback() ");
}
}
}
The debugger doesn't work that way. With very few exceptions, it will not switch threads without explicit instruction from you.
When you are stepping through the Connect() method you wrote, you are debugging a particular thread in your program. The ConnectionCallback() method, if and when it is called (note that it is not generally going to be called synchronously during your call to BeginConnect()), will be called in a different thread. If you want to debug it, you need to set a breakpoint at or in the ConnectionCallback() method itself.
With a breakpoint set in that method, you are assured that the debugger will pause the execution of your program there, regardless of which thread is executing that method.
EDIT:
Thank you for the full code example. Assuming that is in fact the code example you are testing with and having trouble with, then your problem is (as was already guessed) one of two things:
After stepping through the call to the Connect() method, you do not resume execution of your program. I.e. you did not click the "Continue" button or use the "Continue" menu item in the "Debug" menu. Or…
You do resume execution of your program, which then promptly exits before the connection attempt can be resolved.
In case #1 above, you never see the breakpoint because your program is not executing. The breakpoint can only be triggered if execution of the program does in fact arrive at the breakpoint. But the execution of your program can't arrive there if it's not happening at all.
In case #2 above, you never see the breakpoint because your program is not executing. In this case, it's because the program has exited altogether.
If you want to see the breakpoint at the ConnectionCallback() method get triggered, you need to let the program run, and for long enough for that to happen.
As a quick proof-of-concept, I set a breakpoint at that method, and added this statement to the end of the Main() method:
Thread.Sleep(TimeSpan.FromMinutes(5));
I then used the debugger to step through the Main() method. It of course paused to let the program run at the above statement I'd just added, but then very quickly interrupted the program again, right at the desired breakpoint. (I didn't have to wait anywhere close to 5 minutes…I just used that as a very large time value that I was sure would be enough).
For what it's worth, I also tried a test where I stepped through the original Main(), i.e. without the call to Thread.Sleep(), but waited about 5-10 seconds after stepping over the call to Connect() before proceeding. In that case, at least on my computer, I also did see the breakpoint triggered. That particular test is somewhat dependent on machine configuration, so it's less reliable than adding the call to Thread.Sleep(). But it did work in my case.
I think you may have misunderstood what BeginConnect does. That doesn't make the connection - it just starts making the connection, asynchronously. So yes, I'm not at all surprised that "step over" immediately steps to the next statement - that's working as intended.
However, I would have expected that a breakpoint in ConnectionCallback would be hit - that's what you should concentrate on as a problem. That's also where you should put the exception handling, as that's where any problems with making the connection would be found.
Alternatively, if you're using C# 5 or higher, you should look into using async/await, which would allow you to get rid of all the callbacks. Then you'll get a much more familiar experience when debugging - if you step over that line, it really will be connected (or there'll be a failure) by the time you hit the next line. Just be aware that other things may happen (even on the same thread) while it's "awaiting" the response.
Unfortunately, I can't see anything in Socket which implements the relevant pattern. You could use TaskFactory.FromAsync to adapt the "old" style to the "new" style, but it's likely to be fairly painful.
Another approach is to try to move to higher-level constructs like TcpClient instead of the lower-level Socket class.
i want to get signal from port and I used these functions for receiving data,but I sometimes get this exception on line thread.join() :
System.IO.IOException was unhandled
Message="The I/O operation has been aborted because of either a thread exit or an application request.
when I insert a breakpoint and debug it, it goes correct until on line thread.join() and the UI then is stopped and nothings occurs.
also when I run my program in release mode it works correctly but the problem is with debug mode,what is goes wrong and how I can solve this problem?
thnx.
public SignalReader()
{
thread = new Thread(new ThreadStart(ThreadMain));
}
public void Start(string portName, int rate)
{
Stop();
try
{
port = new SerialPort(portName, rate);
port.Open();
}
catch
{
;
}
thread.Start();
}
public void Stop()
{
try
{
if (port != null)
{
if (port.IsOpen) port.Close();
if (thread.IsAlive) thread.Join();
port.Dispose();
port = null;
}
}
catch (Exception ex)
{
MessageBox.Show("4:" + ex.ToString());
}
}
when i swap the order of closing the port and joining the thread:
...
thread.Join();
port.Close();
...
the same story exists.
You are jerking the floor mat, closing the port while it is being used. Most typically in a SerialPort.Read() call. So, yes, that call is going to fail, there's no floor mat anymore. What's missing is a catch block that catches that exception and lets the thread end gracefully. And complete the Join() call.
It is not entirely unusual to do this, as long as you can make sure that the thread is actually blocking on such a Read call. That's not usually very hard to guarantee. But certainly fret about not getting that exception in the Release build, that's not normal. Use the debugger's Debug + Window + Threads to see what's going on in that worker thread.
So just add the required try/catch to fix your problem. Using the SerialPort.DataReceived event is an entirely different approach. Not cleaning up at all, just setting the thread's IsBackground property to true so it automatically dies when the program terminates is also a quite acceptable solution.
The error you are receiving is because of that Stop() you are using in:
public void Start(string portName, int rate)
{
Stop();
try
{
port = new SerialPort(portName, rate);
port.Open();
}
catch
{
;
}
thread.Start();
}
The app is doing something already and when you call this it closes a port is being in use somewhere.
Try removing it and you will get an exception in the Start method if the port is not closed. It will give you a better idea where this error comes from. Also could you paste the part of the code where you are using these methods?