I use VS2012 for my project, I am handling the Socket exception when server cannot send message to target machine but It occurs that when It cannot send msg (I already put it in trycatch) Debugger just break in catch block and say the error without send forward to parent catch block. Please tell me, if I did something wrong.
private void sendMessageToTarget(string Message, IPAddress targetAddress, int port)
{
TcpClient client = new TcpClient();
IPEndPoint server = new IPEndPoint(targetAddress, OUT_MESSAGE_PORT);
Thread senderThread = new Thread(new ThreadStart(delegate()
{
try
{
client.Connect(server);
MemoryStream memstream = new MemoryStream();
NetworkStream netstream = client.GetStream();
byte[] sentString = Encoding.ASCII.GetBytes(Message);
netstream.Write(sentString, 0, sentString.Length);
memstream.Close();
netstream.Close();
client.Close();
}
catch (SocketException ex)
{
throw;
}
}));
senderThread.Start();
} // Sending Message Method
Above is my code for sending message to target
try
{
sendMessageToTarget("CONN_CHECKER", target, OUT_MESSAGE_PORT);
}
catch (Exception se)
{
ConnectedUsers.Remove(target.ToString());
UpdateConnectedUserToTeacher();
if (NeedFollowStudents.Contains(target.ToString()))
{
NeedFollowStudents.Remove(target.ToString());
}
UserLostConnection(this, new EventArgs());
}
And this is the method in another function that I want the action to be performed.
There is no magical marshalling exceptions from one thread to another. It is even almost guaranteed that code after senderThread.Start(); will be executed before code in the thread's delegate.
You function that you pass to Thread constructor becomes top level function on a new thread. If such function throws exception (like you do) this exception will go to AppDomain.UnhandledException event and than normally terminates application.
Your options
revert to synchronous code (all code on one thread)
use existing asynchrnous methods that will notify your code about end of operation. Depending on approach notification can be either via event (similar to WebClient.DownloadStringAsync ) or via callback and calling EndXXXXX like Socket.BeginSend
use async
manually implement synchronization and marshalling exception to original thread.
Note that only synchronous version of the code will work the way you want, all other that use multiple threads will not be able to return exception to the same "parent function" (using async will at least allow your code look the way you want even if it will not work the same way).
This is just a guess, but I believe you should only put a Try/Catch in the parent function and not in the child. When the exception occurs it will show in the parent method. The way you have it written will catch the exception in the child method and it will not get passed back to your parent method.
Related
I'm trying to use ManualResetEvent to make a semaphore-like situation and I have placed WaitOne, Set and Reset in their right places. The WaitOne instruction is called in a listener thread and is places right after a tcp reading:
var networkStream = _clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, Convert.ToInt32(_clientSocket.ReceiveBufferSize));
_mainthreadControl.WaitOne(Timeout.Infinite);
And Set and Reset instructions are called in another thread, so the socket won't get competed over:
try
{
//some code
_mainthreadControl.Reset();
//some code that uses the same socket as above
_mainthreadControl.Set();
}
catch (Exception ex)
{
//ignored
}
But I need the code to stop when it reaches Reset, and only continue after the WaitOne is reached (and executed), so the code below Reset only runs after the competing thread is waiting.
I don't know if I was clear enough, so I'm glad to add details as needed. Thanks in advance.
If it suites for you. Please try to use additional AutoResetEvent. Like this:
var _additionalControl = new AutoResetEvent(false);
// code gap
var networkStream = _clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, Convert.ToInt32(_clientSocket.ReceiveBufferSize));
_additionalControl.Set();
_mainthreadControl.WaitOne(Timeout.Infinite);
// code gap
try
{
//some code
_mainthreadControl.Reset();
_additionalControl.WaitOne(Timeout.Infinite);
//some code that uses the same socket as above
_mainthreadControl.Set();
}
catch (Exception ex)
{
//ignored
}
In turn I recommend to use System.Threading.Monitor class, cause it's more faster than ManualResetEvent(false), because it's restricted by the single process. If course if you don't need to use lock in another program.
I have a program that deals with socket communication asynchronously. The exception I've been getting only occurs in release build (on build machines). The code that causes the problem is really simple routine to start listening for incoming socket connections:
public async Task Listen()
{
try
{
var endpoint = new IPEndPoint(IPAddress.Loopback, Port);
using (Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Socket.Bind(endpoint);
Socket.Listen(Limit);
while (!Shutdown)
{
var socket = await Socket.AcceptAsync().ConfigureAwait(false);
// some code handling connection
var result = await Socket.ReceiveAsync(state).ConfigureAwait(false);
Received(result, state);
}
}
}
catch (ObjectDisposedException) {}
catch (Exception ex) when (ex is SocketException || ex is ApplicationException || ex is ThreadAbortException)
{
OnError?.Invoke(this, ex);
Dispose();
}
}
AcceptAsync and ReceiveAsync are extension methods that use TPL pattern with Task.Factory.FromAsync. The exact exception is following:
Exception Type: System.InvalidProgramException
Exception Message: Common Language Runtime detected an invalid program.
This seem to occur in:
System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start
The exception is generated instantly when call is made to this method. Any ideas what might be wrong?
According to MSDN, this exception informs the user about invalid IL code. So something could be broken in the framework. I recommend you to try your luck at Connect.Microsoft. Also, if you're really interested and are looking for a quick fix you may want to inspect the IL code of the failing methods' chain.
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?
in server -(multi)client application [TCP]. I use Socket, NetworkStream, StreamReader and StreamWriter for each client i Accept in the server .. so i have couple of questions :
Do i have to dispose all of them when i want to close the connection with a client?
If the client Disposes the Socket that's connected with the server .. do i also have do dispose that socket in the server side ,or it closes automatically ?
in my code here :
Thread thAccept = new Thread(acceptClient);
Thread thJob;
private void acceptClient()
{
while (true)
{
Socket client = server.Accept();
Console.WriteLine(client.RemoteEndPoint+" has connected");
StreamReader reader = new StreamReader(new NetworkStream(client));
//is it ok to create an instance NetworkStream like this or i will have to dispose it later?
thJob = new Thread(Job);
thJob.Start(reader);
}
}
private void Job(object o)
{
StreamReader reader = (Socket)o;
try
{
string cmd = null;
while ((cmd = reader.ReadLine()) != null)
{
//(BLA BLA..)
}
}
catch
{
Console.WriteLine("Disconnected by catch");
}
finally
{
Console.WriteLine("Finally Done.");
reader.Dispose();
}
}
is that code fine to dispose all (needed to be disposed) objects?
This is not a duplicate.
Your code differs from the linked duplicate because in your code, the IDisposable is handed off to another thread.
The general rule is that if you create an object that implements IDisposable, then you're responsible for calling Dispose on it when you're finished with it. When possible, that should be done in a using block, to ensure that Dispose is always called. In your case, your code is not finished with the object until the other thread is exited. In that thread, you correctly call Dispose in the finally block.
If you had called Dispose on the NetworkStream, then it would have closed the StreamReader as well, which would defeat your purpose. I suspect it would be the same thing if you had called Dispose on the Socket. As such, your code is correct as-is.
The object on the client side has no relationship with the object on the server side, except through TCP/IP. The fact that the client may call Dispose on its socket doesn't mean that the server has to call Dispose on its socket. However, once the server is finished reading data from the socket, and the connection is closed, the server-side socket should be Disposed. I don't know for certain, but I believe that when the StreamReader is disposed, the underlying NetworkStream will be disposed, which should call Dispose on the socket from which the stream was created.
Your code is fine, except for some unrelated issues: you don't need to set cmd to null, since you're going to set the value in the next statement. Also, you should not use an empty catch block like that. You have no idea what exception was thrown, but you will ignore it anyway, without even logging or displaying the exception. At the least, you should do
catch (Exception ex)
{
Console.WriteLine("Disconnected by exception " + ex.ToString());
}
finally
{
Console.WriteLine("Finally Done.");
reader.Dispose();
}
I was told several times that async is better or that I should use async instead of sync sockets and as such started learning it, but am already having difficult.
I've got the basic feel of how the callback works and how to establish a connection.
I am using this msdn code as reference!
A few problems I am having with the code:
Currently that code will connect to the server, send a text, read the response and exit. How do I do so I can keep receiving the data until either the server disconnects me and/or I end it by myself ? I am not much sure on how I should do it, if I would need to wrap it on a thread with while or simple call that Receive again once the ReceiveCallback is done.
Another things I've noticed is when it connects, the socket is assigned to client but the code itself is always reassigning the client socket which I don't understand very well compared to the sync socket we have a main socket that we are always consulting etc.
I am not sure on how old the reference I am using is but would appreciate if you could help me with examples of what I have pointed out as it is easier for me to understand.
UPDATE:
private void SetupRecieveCallback(Socket sock)
{
new Thread(
delegate()
{
while (isReceiving)
{
_receiveQueue.Reset();
try
{
AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
sock.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock);
}
catch (Exception ex)
{
_logger.Error("Setup Recieve Callback failed! " + ex.Message);
}
_receiveQueue.WaitOne();
}
}
).Start();
/*
// The original code
try
{
AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
sock.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock);
}
catch (Exception ex)
{
_logger.Error("Setup Recieve Callback failed! " + ex.Message);
}
*/
}
Simply call BeginReceive() again in the callback to keep receiving. When the server breaks the connection then your callback will be called and EndReceive() throws an ObjectDisposedException. That's how you know to stop calling BeginReceive().
Second question is harder to decode (ask only one). I'm guessing you are puzzled about this statement:
private static void ConnectCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket client = (Socket) ar.AsyncState;
// etc..
No reassigning the socket is happening here. The code simply retrieves a reference to the original socket. Which is a useful technique, it allows this callback to be used by more than one connection. The ar.AsyncState value got to be the socket by this statement:
client.BeginConnect( remoteEP,
new AsyncCallback(ConnectCallback), client);
Note how client is passed to the AsyncCallback constructor. The exact same client that's retrieved in the callback. Any object can be passed.