Websocket compatibility issues - c#

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__

Related

Leaf.xNet.HttpException: "Could not receive the message body of the response HTTP-server 'example.com'"

This error appears only on this link, other links work correctly
Internal exceptions (1/2) - IOException: Unable to read data from the transport connection. An attempt to establish a connection was unsuccessful because the required response was not received from another computer within the required time, or an already established connection was terminated due to an incorrect response from an already connected computer.
Internal exceptions (2/2) - SocketException: An attempt to establish a connection was unsuccessful because the required response was not received from another computer within the required time, or an already established connection was terminated due to an incorrect response from an already connected computer.
I tried to add different headers, cookies, or make a default "clean" request.
Moreover, the postman correctly receives the body, as well as HttpClient.
I will be glad if you help.
For some sites it is not possible to make requests with this framework. Solved the problem by rewriting the code on HttpClient.

.NET/C# to MySql running on linux - exception on first command, but subsequent commands do work

Have a really crazy situation. I can't post specifics, so I'm just looking for general guidance. We have already opened a ticket with Oracle/MySql support. I'm just looking to see if anyone else has run into this situation or anything similar. Here is our scenario:
Windows 2012 R2 Server with .NET 4.7.1 running.
Simple Windows Forms .NET application.
We are trying to run a simple query against a Linux MySql Server. MySql is Enterprise Version 5.7.x.
On the first attempted connection, the Windows Forms app locks the UI, waits about 15 seconds, and then reports back that there is an error running the command. The error is shown below.
System.ApplicationException: An exception occurred on the following sql command:select * from tablename where compl_date >= '2019-12-17 04:44:34 PM' ---> MySql.Data.MySqlClient.MySqlException: Authentication to host 'ip address' for user 'userid' using method 'mysql_native_password' failed with message: Reading from the stream has failed. ---> MySql.Data.MySqlClient.MySqlException: Reading from the stream has failed. ---> System.IO.EndOfStreamException: Attempted to read past the end of the stream.
When this error pops up, if I click on the "Continue" button, subsequent calls to the database work as intended (at about a 95% rate).
On the server, the mysqld error logs are shown below for the first call. Subsequent calls do work.
2019-12-16T22:06:29.554171Z 3496 [Warning] IP address 'client ip address' could not be resolved: Name or service not known
2019-12-16T22:06:50.188443Z 3496 [Note] Aborted connection 3496 to db: 'drupaldb' user: 'userid' host: 'ip address' (Got an error reading communication packets)
2019-12-17T02:53:17.832725Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 11355ms. The settings might not be optimal. (flushed=0 and evicted=0, during the time.)
2019-12-17T03:25:18.200855Z 3527 [Note] Got an error reading communication packets
2019-12-17T03:25:37.167395Z 3528 [Note] Got packets out of order
2019-12-17T03:25:37.382512Z 3529 [Note] Got packets out of order
2019-12-17T03:25:47.688836Z 3530 [Note] Bad handshake
2019-12-17T14:26:33.619967Z 4803 [Note] Got timeout reading communication packets
2019-12-17T19:34:34.741441Z 4851 [Note] Got timeout reading communication packets
2019-12-17T19:47:47.595426Z 4853 [Note] Got timeout reading communication packets
2019-12-17T19:48:45.586357Z 4854 [Note] Got timeout reading communication packets
If you have some general ideas, let me know.
FYI, we have some other linux/mysql instances, and this runs just fine.
At this point, we think we have solved the problem, at least for the short term. Both server and client are sitting on a private network. We think that the database server is trying to send a certificate to the windows client. The windows client is also on this private network. We think the Windows Client is not accepting the ssl certificate and that this is causing the failure on the first connection attempt. By adding the option "SslMode=None", this seems to resolve the issue.
Blog post we found that helped us: https://blog.csdn.net/fancyf/article/details/78295964

HttpContext.Response underlying socket shuts down unexpectedly

I have a HttpListener that listen for any file requests on the localhost (i.e 192.168.0.10/Foobar.ext) on the specified port (in this case specifically it is a HLS stream using .m3u8 header files and .ts video files. But the system should work for any type of file).
IAsyncResult result = listener.BeginGetContext(new AsyncCallback(HttpRequestListenerCallback), listener);
result.AsyncWaitHandle.WaitOne(1);
When a request is made the callback creates a HttpListenerContext for the requested file (and that file only), and extracts the file name like this:
HttpListenerContext context = listener.EndGetContext(result);
string fileName = context.Request.Url.AbsolutePath.Substring(1);
the context gets added to a dictionary called httpContexts and linked to an int commandSequenceNumber to keep track of requests.
If the Filename is valid a requests gets send to the server to download the file. The file gets downloaded and gets put into a byte array called totalBufferdata. up to here everything works perfectly.
Now I want to write the byte data of the requested (video)file back to the response (HttpListenerContext.Response) of the context on which the file was requested
To do this i use the following piece of code (this happens after the file has been completely downloaded):
HttpListenerResponse response = httpContexts[commandSequenceNumber].Response; //Get the appropriate context from the dictionary
response.ContentLength64 = totalBufferdata.Count;//set the length response body
Stream responseStream = response.OutputStream; //The stream to which the repsonse needs to be written
try
{
currentContext.Response.OutputStream.Write(dataNoResponseHeader, 0, dataNoResponseHeader.Length);
}
catch (IOException e)
{
Debug.LogError("Exception in writing to response::" + e);
Debug.LogError("innerException:: " + e.InnerException);
}
currentContext.Close();//close the request and response stream
This sends the response back over the context of the request (I.e 192.168.0.10/Foobar.ext, over the same port.)
Now this works fine, aslong as there is a fast, reliable internet connection. When the internet connnection is slow, or inconsistent I start getting the exception:
System.IO.IOException: Unable to write data to the transport connection: The socket has been shut down. ---> System.Net.Sockets.SocketException: The socket has been shut down
With the inner exception being:
System.Net.Sockets.SocketException (0x80004005): The socket has been shut down
I've looked up what the HResult of 0x80004005 corrolated to on msdn, but that is just "E_FAIL Unspecified failure", so no luck there.
I've been unable to figure out why it would throw an expection of the socket closing down (and why it happens on the localhost part, but only when connectivity is bad). I make sure all the data needed is in the totalBufferData, so a low internet speed shouldn't influence this, as all data is already downloaded before i write it to the response. I made sure i do not close the context prematurely anywhere in my code either.
So far i've been unsuccesful in finding a way to get to the underlying socket of HttpListener. I also tried casting response.OutputStream to a NetworkStream, and get the socket from the NetworkStream, but that cast is not valid (Which confused me as they're both IO streams?). Thinking it may be a closing issue i also tried
using(Stream testStream = response.OutputStream)
{
testStream.Write(totalBufferdata.ToArray(), 0, totalBufferdata.Count);
}
I feel like this issue is related to a timeout somewhere. But the Listener doesn't hit the default time-out time. According to MSDN all default time-outs should be 2 minutes. To which I get nowhere close. And i think that the exception returned in case of a time-out should be ObjectDisposedException Write(Byte[], Int32, Int32) was called after the stream was closed. as I would imagine timing out would dispose of the connection, instead of crash it? Is that a misunderstanding?
The requests and reponses are done on seperate threads. But a request that gets done while a response is still in progress gets queued up, and waits for the response to finish before it starts a new response.
Is there a way to get and debug the underlying socket to find out why it closes/crashes? Or maybe an alternative approach to requesting a file over localhost, and responding to this that doesn't use HttpListener?
Some additional information: It is for a Unity application (Unity 2019.1) using scripting runtime version .Net 4.x equivalent, with .Net 4.x api compatibility level and IL2CPP scripting backend. But neither of the classes handling the request or response inherit from monobevahiour (which isn't even possible on threads in unity). Building for Android.
The bounty has ended, but I will open a new one fpr whoever has some valuable information!
See this blog posts that show how to stream a video file using aspnet webapi with the PushStreamContent.
https://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/
https://www.c-sharpcorner.com/article/asynchronous-videos-live-streaming-with-asp-net-web-apis-2-0/
This sounds like a problem that I have run into before, with the information given that the internet is slow and or unreliable, I would suggest possibly looking to using a UDP socket instead of TCP as they don't throw exceptions when the connection is cut briefly, or if small amounts of data are lost during transmission, see here. The api is very similar, see here. It would probably be a bit cumbersome to reimplement, but I think it'll solve your problem.
My other insight would be that you're try catch block is specifying that it only accepts IOExceptions, even though it's catching a SocketException, most of the time I just use the generic Exception class to avoid trying to determine which exceptions will be thrown from where.
Just change:
catch (IOException e)
to
catch (Exception e)
Both IOException and SocketException inherit from the Exception class, so the rest of the code remains unmodified. This should give you some more problem specific information hopefully.
You may have some problems there.
First would be a TimeOut situation. Is possible that, because you're experiencing some problems on the internet, that the time to between request and response si bigger than the specified (i believe if you don't, it's set by default to 60 seconds).
Another thing would be that the file size may be to big to write completly at one single package response. But that would happen in any request, not only on the "bad" internet connnection moments.
It's also possible that, because the internet connection is unstable, your "server" detects that the "client" disconected (even briefly), therefore closed the socket.

Wince Socket exception on asynchronous HTTP request

I am writing a WinCE app in C# that makes an HTTP POST to an APACHE server residing on my network. Because of some network issues (I am guessing), I get the following exception in the managed code
System.Net.Sockets.SocketException occurred
Message="A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond"
ErrorCode=10060
NativeErrorCode=10060
StackTrace:
at System.Net.Sockets.Socket.ConnectNoCheck(EndPoint remoteEP)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at System.Net.Connection.doConnect(IPEndPoint ep)
at System.Net.Connection.connect(Object ignored)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
This exception isn't always thrown, but when it is thrown, my app fails to connect to the server AT ALL. Repeated connection attempts don't help in reconnecting either. The only thing that helps is closing and re-deploying the app.
I can't catch the exception because its inside of managed code. Is there any way to circumvent this and close all socket connections to my server and re-initialize them? Is there something I am doing wrong?
The exception message looks a bit misleading ("connection attempt failed because the connected party") but I think it means your hardware is communicating with the server, but the server is not accepting the connection on the TCP level.
A problem I could think of is "hanging" connections, causing the server to reach the maximum number of concurrent connections and to stop accepting new ones.
Although it's just a guess, you might want to check the apache log if you can to see if you can find out if the server reports anything, and perhaps try restarting apache as soon as the problem occurs again. If that helps, you still need to find the cause of course.

How can you get Socket.Shutdown to raise a SocketException?

MSDN states that Socket.Shutdown can throw a SocketException. I've had this happen to me in production recently after introducing a load balancer between my clients and my server. But I cannot reproduce it in testing without a load balancer. Can you?
Some background - I have a server application written in C# that uses TCP sockets to communicate with clients. The application protocol is very simple for the server: accept connection, read request, send response, wait for client shutdown (read expecting 0 bytes), shutdown.
This code has been in production without issue for many years. However after introducing a load balancer in front of multiple server machines one of the server processes crashed due to an unhandled SocketException that was raised when the server called Socket.Shutdown. The particular client had timed out whilst waiting for the server to respond and attempted to close the connection early. The exception message on the server was "An existing connection was forcibly closed by the remote host." It is not unusual for the client to do this, but obviously prior to the load balancer the server was raising this error at a different point in the code. Still it's clearly a server bug and the fix is obvious - handle the exception.
However using a test client application (also written in C#), I cannot find a sequence of operations that will cause the server to raise an exception during Socket.Shutdown. It appears that the load balancer did something unusual to the TCP packets, but still, I dislike using that as excuse for failing to reproduce the issue.
I can run both server and client code in debug and I have WireShark watching the packets.
On the client side, after the connection is established, the operations are:
Socket.Send() // single call
Socket.Receive() // this one times out in our scenario
Socket.XXX() // various choices as described below
On the server side, after the connection is established, the operations are:
1) Socket.Receive() //multiple calls until complete message is received
2) // Processing...
3) Socket.Write() //single call
4) Socket.Receive() // single call expecting 0 bytes
5) Socket.Shutdown()
Presume each call is wrapped with try..catch(SocketException)
A) If I pause the server during step 2, wait for the client to time out, and initiate a client shutdown using Socket.Shutdown(SocketShutDown.Send) a FIN packet is sent to the server. When the server resumes processing, all the calls will succeed (3 thru 5) because that's a perfectly acceptable TCP flow.
B) If I pause the server during step 2, wait for the client to time out, and initiate a client shutdown using Socket.Shutdown(SocketShutDown.Both) or Socket.Close() again a FIN packet is sent to the server. When the server resumes processing step 3 succeeds, but it causes the client to send a RST packet in response as it is not accepting more data. If this RST arrives before step 4 then Socket.Receive throws and step 5 succeeds. If it arrives after step 4, then Socket.Receive succeeds (returns 0 bytes), and yet step 5 succeeds.
C) If the client has "Dont Linger" set (Linger enabled with 0 timeout), and I pause the server during processing, wait for the client to time out, and initiate a client shutdown using Socket.Shutdown(SocketShutDown.Both) or Socket.Close() a "RST" packet is immediately sent to the server. When the server resumes processing steps 3 and 4 will fail but still step 5 succeeds.
I think what puzzles me most is that Socket.Shutdown appears to ignore my test client RST packets and yet evidently my load balancer was able to send a RST packet that was not ignored. What am I missing? What else can I try?

Categories