get socket error string when async connect fails
I'm having the same issue as described. I have found a bit of a workaround:
I wrap each of my 'streams' in a Stream
class and set a timeout property. Before I call connect, I generate a timestamp of when the timeout should occur. I then have a loop in a Manager
class which calls stream_select()
.
Successful connections are placed in the $write
array. I have another call at the bottom of the loop that calls $stream->checkTimeout()
. Within that there is a stream_select()
call with 0 set for tv_sec
and tv_usec
. If $this->conn doesn't appear within $write
, I assume it has timed out.
C# async SocketException while binding
So the obvious things to check - Something is already listening on port 8192 or there's some other reason why your machine would reject your program opening that port (firewalls, etc).
The other problem is while you are blocking binding twice with the "Running" check, you're only doing that for the instance of listener - hitting the button will create a whole new listener and attempt to have it listen on port 8192 - which since you already have a listener bound there, will fail with that exception.
error after receiving data over TCP/IP connection using Asynchronous socket communication in c#
You are somehow magically expecting to know when you have received a "message" despite not even having decided what a message is or writing any code to determine whether one has been received.
There is an old saying in the TCP programming community -- nobody is allowed to write any code that uses TCP until they can 100% explain what every word in this true statement means:
"TCP is a reliable, byte-stream protocol that does not preserve application message boundaries."
You have to code to implement a "message". TCP is a byte-stream protocol. If you want to send and receive messages, you'll need to create a protocol that does that.
Start by defining what a message is, how one is delimited, and so on. Then write code to send and receive messages according to your definition. When your onReceive
function is called, that just means the TCP/IP stack received some bytes -- you need to decide whether that's a message or not by following the rules for a the messaging protocol.
Handling exceptions in asynchronous socket callbacks
"How do I report exceptions?" is a pretty broad question. It's hard to know for sure what specific advice would be best in your case, as there are many options for solving the problem.
That said, there are some general rules that IMHO you should always follow, and these can help direct your design:
- Do not block I/O threads with UI.
This means that for sure, your code example should be improved, as you are delaying any I/O thread used to call your callbacks while waiting for the user to acknowledge the error message.
- Observe the general OOP principle of "separation of concerns".
In other words, even if the thread that is presenting the error message isn't an I/O thread, it's still not a good idea to have user interaction logic inside a class that's main purpose is to handle network I/O.
There are of course other useful rules for programming, but I think the above two are most relevant considering your current code example. So, how to address these?
At a minimum, I would change your current implementation so that none of the I/O code was in the MyForm
class. The MyForm
class is for user-interface; it should not involve itself with the mechanisms of network I/O, but rather should delegate that work to some other class.
Now, that other class still needs to communicate with MyForm
. But it should do so in a way that is independent of MyForm
, i.e. which is not tied to (or "coupled") the class. In terms of reporting exceptions, one common way to accomplish this is to declare an event that is raised whenever an exception occurs.
That would address the second point, but the first point is still an issue. It can be resolved by using the Control.BeginInvoke()
method to execute the event-handling code in the form object, so that that code is executed in the UI thread, and asynchronously relative to the I/O thread (i.e. the BeginInvoke()
method doesn't wait for the invoked code to complete before returning).
Putting all that together, you might get something like this for example:
class ExceptionReportEventArgs : EventArgs
{
public Exception Exception { get; private set; }
public ExceptionEventArgs(Exception exception)
{
Exception = exception;
}
}
class MyNetworkClient
{
public event EventHandler<ExceptionReportEventArgs> ExceptionReport;
private void OnExceptionReport(Exception exception)
{
EventHandler<ExceptionReportEventArgs> handler = ExceptionReport;
if (handler != null)
{
handler(this, new ExceptionReportEventArgs(exception));
}
}
// For example...
private void ClientConnectCallback(IAsyncResult asyncResult)
{
try
{
/* code omitted */
}
catch (SocketException sockEx)
{
// if the server isn't running, we'll get a socket exception here
OnExceptionReport(sockEx);
}
catch (ObjectDisposedException)
{
}
catch (Exception ex)
{
OnExceptionReport(ex);
}
}
}
partial class MyForm : Form
{
private MyNetworkClient _client;
public MyForm()
{
InitializeComponent();
_client = new MyNetworkClient();
_client.ExceptionReport += (sender, e) =>
{
BeginInvoke((MethodInvoker)(() =>
MessageBox.Show(e.Exception.Message, Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Error)));
};
}
}
Now, all that said: as I mentioned, there are lots of ways to address the basic issues. An alternative to the above would be to use the async
/await
pattern, which provides a mechanism to cleanly write asynchronous logic in an easy-to-read, imperative-style way, while still allowing for correct transitions between code that has to execute in the UI thread and code that does not.
I won't go into a lot of detail on that point — there are a lot of examples around, and it would require a much larger rework of the code you posted — but the basic idea would be to use e.g. NetworkStream
, which has built-in async
methods to handle the I/O, and to let exceptions "bubble up" from the I/O methods.
In this approach, you wouldn't need the ExceptionReport
event. Instead, your MyNetworkClient
class above would offer async
methods that a controller-class (e.g. your MyForm
object) can call to initiate I/O. If an exception occurs, each async
method in the call stack can handle (if needed) the exception but then rethrow it (i.e. with a plain throw;
statement), all the way back to the UI code, where the exception will be raised in the UI thread and can be presented to the user there, without blocking an I/O thread.
I think in general, the key is to just keep in mind the usual rules and stick with them. Ultimately, you will find the code is easier to write and understand, and will behave better in your chosen UI framework (e.g. Winforms).
Unable to connect to asynchronous server using async/await
In your console application, when you run this the application will actually close immediately. You need to invoke the .Wait()
on the Run
method to prevent this:
static void Main(string[] args)
{
Run().Wait();
}
Additionally, your Run
method should be defined like this (Task
returning):
static async Task Run()
{
// Omitted for brevity...
}
Otherwise, it is fire-and-forget.
Error after connection restored Socket C#
If, after a request to the server, the connection is terminated, and after 15 seconds, it is restored, an error appears.
If you unplug the network cable, Windows tells sockets over that NIC that they're disconnected. Otherwise (say your cable is still plugged in, but a cable, switch or router in between ceases to function), you need to send or receive on that socket in order for it to detect it's been disconnected.
See How to check if a socket is connected/disconnected in C#?.
Once disconnected, a socket cannot be restored. You need to detect this status, start a new connection and tell your server that you want to continue a prior transmission. We don't know whether your protocol understands that.
Also: IEnumerable<byte> data
, data.Any()
, new ArraySegment<byte>(data.ToArray())
- why?
Related Topics
Profiling Arbitrary Cuda Applications
Git - Crlf Issue in Windows + Linux Dual Boot
How to Connect to Sftp Using Linux Command from Perl
Unix/Linux Ipc: Reading from a Pipe. How to Know Length of Data at Runtime
To What Extent Can One Rely on Writing to Disk When Sigterm Is Given
Trouble with Installing Nloptr by Locally on Ubuntu
Mmap Flag Map_Uninitialized Not Defined
Linux Device Driver Unsafe Fxsave/Fxrstor Bug - Any Precedents
Mpc/Mpd on Linux: How to Play Local Wav File
Add Timestamp to Cat Output from Shell Script
Creating an Alias in Ubuntu, in .Profile
How to Force a Range of Virtual Addresses
How to Rename a Shared Library to Avoid Same-Name Conflict
Reading Kernel Memory Using a Module
Svn Keeps Prompting Me for Passwords and Refuses to Cache My Credentials