Get a StreamSocket's Connection Status (UWP) - c#

I'm using a StreamSocket in a Windows Universal app to make a TCP/IP connection to a text based game (the socket is left open for an extended period of time). I have it connecting and returning data fine. Most socket implementations I've used in the past have a property or function (or a way to poll the socket) and get the status (whether it's open, closed, broken, pending, etc.).
I haven't been able to find a way to do this with the StreamSocket.
My question is, How do I query the status of the StreamSocket connection to see if it's dropped (without waiting until I send something down the pipe for it to error out)?
E.g., something so I could do something like:
if (this.Socket.Status != Status.Connected)...

if (this.Socket.Status != Status.Connected)
The code you wrote was quite elegant , however, as far as I know there is no such api provided by uwp.
The Windows.Networking.Sockets namespace has convenient helper methods and enumerations for handling errors when using sockets and WebSockets. This can be useful for handling specific network exceptions differently in your app.
An error encountered on DatagramSocket, StreamSocket, or StreamSocketListener operation is returned as an HRESULT value. The SocketError.GetStatus method is used to convert a network error from a socket operation to a SocketErrorStatus enumeration value. Most of the SocketErrorStatus enumeration values correspond to an error returned by the native Windows sockets operation. An app can filter on specific SocketErrorStatus enumeration values to modify app behavior depending on the cause of the exception.
For parameter validation errors, an app can also use the HRESULT from the exception to learn more detailed information on the error that caused the exception. Possible HRESULT values are listed in the Winerror.h header file. For most parameter validation errors, the HRESULT returned is E_INVALIDARG
.

Related

Websphere MQ isConnected variable after exception

I use an C# Console Application to put and read messages of the MQ..
When the application starts, it connect once with the MQ and then the connection should be always upholded.
The program runs every 30 sec and check if new messages are in the queue or a database(to put them on the queue) and check the isConnected-variable if its true.
But what happen if an exception(2009 - connection broke) in the Put/Get occur? Will the isConnected automatically set to false?
Is the connection automatically disconnected or do I have to call Disconnect() in the error handling?
Thanks!
To answer your exact question, for a basic .net application (non XMS) using MQQueue for put/get, if you get CERTAIN bad return codes from the underlying API call which indicates a connection issue, MQ will attempt an MQBACK and an MQDISC for you and will result in the connection handle being invalidated (IsConnected would return false) and an exception being thrown. However if an exception occurs outside those return codes then no attempt is made to do anything with the connection.
Basically you should not code an application relying on this behaviour, when the most simple answer is to always disconnect if you get an exception which relates to the quality of the connection or queue manager. For example, a no message available etc type exception doesnt mean you need to disconnect but a connection broken obviously does. There is no harm in calling disconnect on an already disconnected connection.

Telling When Couchbase Query Times Out

I am using couchbase using the .NET client to interact with it. I need to be able to differentiate the cause of a failed call to my couchbase box and log them accurately. I've tried provoking a timeout in my testing environment but I have been unable to.
Reading the .net client documentation it appears that ExecuteGet returns an IGetOperationResult object that contains both an exception property and a status code property. The status codes would appear to correspond to this table. I haven't found in the documentation for the .NET client as to whether or not it throws an exception like the Java client. Also, the status codes from the memcached table doesn't seem to have a clear status code value that corresponds to a timeout.
How would one tell whether or not the configured timeout has been exceeded from a call besides not having a value returned?
The StatusCode property is set only when a response from the server is sent. A timeout would result in no response from the server, therefore a null StatusCode. A connection timeout should result in the Exception value being populated on the GetOperationResult...
https://github.com/couchbase/couchbase-net-client/blob/2dc8a63208dfa8b991290d128b14002ad4c43f53/src/Enyim.Caching/Memcached/PooledSocket.cs#L68
However, it is quite possible that somewhere further up the Enyim stack, the original timeout exception is being swallowed and rewrapped in another exception. When you experience timeouts, are you seeing any value for the Exception property?

Websocket compatibility issues

I am using the plain C# await httpListenerContext.AcceptWebSocketAsync(subProtocol: null), everything seems to work great and data is being sent and transmitted from Chrome successfully, however sometimes the connection seems to get dropped for no reason or the client will send the data partially, this is especially annoying since the data is JSON and I will only get half the object (and I am certain I send it full on the client)
I am testing on localhost so any connection issues aren't a possibility (not that they would be anyway because of TCP)
I see that I sometimes receive the following exception:
Error while processing account:The 'System.Net.Web
Sockets.ServerWebSocket' instance cannot be used for communication because it ha
s been transitioned into the 'Aborted' state.:System.Net.WebSockets.WebSocketExc
eption (0x80004005): The 'System.Net.WebSockets.ServerWebSocket' instance cannot
be used for communication because it has been transitioned into the 'Aborted' s
tate. ---> System.OperationCanceledException: The operation was canceled.
at System.Threading.CancellationToken.ThrowOperationCanceledException()
at System.Net.WebSockets.WebSocketHttpListenerDuplexStream.<ReadAsyncCore>d__

TcpClient.BeginRead/TcpClient.EndRead doesn't throw exception when internet disconnected

I'm using TcpListener to accept & read from TcpClient.
The problem is that when reading from a TcpClient, TcpClient.BeginRead / TcpClient.EndRead doesn't throw exception when the internet is disconnected. It throws exception only if client's process is ended or connection is closed by server or client.
The system generally has no chance to know that connection is broken. The only reliable way to know this is to attempt to send something. When you do this, the packet is sent, then lost or bounced and your system knows that connection is no longer available, and reports the problem back to you by error code or exception (depending on environment). Reading is usually not enough cause reading only checks the state of input buffer, and doesn't send the packet to the remote side.
As far as I know, low level sockets doesn't notify you in such cases. You should provide your own time out implementation or ping the server periodically.
If you want to know about when the network status changes you can subscribe to the System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged event. This is not specific to the internet, just the local network.
EDIT
Sorry, I misunderstood. The concept of "connected" really doesn't exist the more you think about it. This post does a great job of going into more details about that. There is a Connected property on the TcpClient but MSDN says (emphasis mine):
Because the Connected property only
reflects the state of the connection
as of the most recent operation, you
should attempt to send or receive a
message to determine the current
state. After the message send fails,
this property no longer returns true.
Note that this behavior is by design.
You cannot reliably test the state of
the connection because, in the time
between the test and a send/receive,
the connection could have been lost.
Your code should assume the socket is
connected, and gracefully handle
failed transmissions.
Basically the only way to check for a client connection it to try to send data. If it goes through, you're connected. If it fails, you're not.
I don't think you'd want BeginRead and EndRead throwing exceptions as these should be use in multi threaded scenarios.
You probably need to implement some other mechanism to respond to the dropping of a connection.

Java Socket Disconnect Reporting vs. C# Disconnection

in C# when a sockets connection is terminated the other node is informed of this before terminating the link thus the remaning node can update the connection status.
in Java when i terminate a communication link the other node keeps reporting the connection as valid.
do i need to implement a read cycle (makes sense) that reports the connection as lost when it recieves a -1 during read (in C# this is 0 i think)?
thank you for your insight.
EDIT: thanks to you both. as i suspected and mentioned in my post that an additional check is required to confirm the connected state of a connection.
If the remote side of the connection goes away, normally you'll get an IOException from the InputStream/InputChannel if the disconnection can be detected. If it can't detect the disconnect an IOException will eventually be thrown when the socket read times out. The length of time it waits for a timeout can be adjusted using Socket.setSoTimeout().
In java, you find out about the other end of the socket being closed only when you read/write to/from the socket, or query the input stream state (e.g. InputStream.available()). I don't think there is any asynchronous notification that the other end is closed.
How are you testing that the socket is still open?
You can poll the InputStream.available() method and if that returns -1, you know the socket is closed. Of course, you can also read data, if that fits with your usage.
See InputStream.available()

Categories