How Is an Error Reported from Async Socket Connect

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:

  1. 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.


  1. 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



Leave a reply



Submit