sta / websocket-sharp

A C# implementation of the WebSocket protocol client and server
http://sta.github.io/websocket-sharp
MIT License
5.73k stars 1.66k forks source link

The header of frame cannot be read from the stream #202

Open Promises42 opened 8 years ago

Promises42 commented 8 years ago

2016-01-21 21:34:01|Fatal|<>cDisplayClass2c.b2b:1601|WebSock etSharp.WebSocketException: The header of a frame cannot be read from the stream . at WebSocketSharp.WebSocketFrame.processHeader(Byte [] header) in C:\User\Promises\Desktop\websocket-sharp-master\websocket-sharp\WebSocketFrame.cs:line 429 at WebSocketSharp.WebSocketFrame.<>cDisplayClassa .b9(Byte[] bytes) in C:\User\Promises\Desktop\websocket-sharp-master\websocket-sh arp\WebSocketFrame.cs:line 529 at WebSocketSharp.Ext.<>cDisplayClass9.<ReadBytes Async>b8(IAsyncResult ar) in C:\User\Promises\Desktop\websocket-sharp-master\websocket-sharp\Ext.cs:line 651 Client Disconnected [An exception has occurred while receiving.]

Chrome: Worked Firefox 39: not working i saw some resolutions in the issue's and i added "this.IgnoreExtensions = true;" to OnOpen but i didnt work.

Server: Windows 7 Client: Windows 7 & Windows XP

sta commented 8 years ago

Hello there,

Could you please describe MORE about both your client and server code?

i saw some resolutions in the issue's and i added "this.IgnoreExtensions = true;" to OnOpen but i didnt work.

That doesn't work in OnOpen. Do it in initializing.

yourServer.AddWebSocketService<YourBehavior> (
  "/YourServicePath",
  () => new YourBehavior () { IgnoreExtensions = true }
);
sassembla commented 8 years ago

so, Thank you for your great work,

I encountered same problem. I could reproduce it and I think this is because of overlay of send & receive. these operation around same stream should be ordered & isolated.

Simply you can reproduce this problem as below.

0. setup the server.
1. connect the client to the server.
2. send 100 character message from the client to the server with 50 message / sec.
3. send 100 character message from the server to the client with 50 message / sec.
4. this causes these errors.

The data length of receiving & sending bytes is actually correct. but payload contents is strongly mixed.

client sending “aaaa” to server -> 
same time, server sends “bbbb” to client ->
client received “bbbb” from server inside of sending “aaaa” ->
client start to read “bbbb” -> 
eventually client received “abbb” + 
server received “baaa”

These degree of data mixing is very random.

and sometimes raises these errors.

logs here.

ReadFrameAsync error, emitted. ex:WebSocketSharp.WebSocketException: The header of a frame cannot be read from the stream.
  at WebSocketSharp.WebSocketFrame.processHeader (System.Byte[] header) [0x00166] in /Users/tomggg/Desktop/Calivers/Assets/Libs/websocket-sharp/WebSocketFrame.cs:475 
  at WebSocketSharp.WebSocketFrame+<readHeaderAsync>c__AnonStorey166.<>m__1E6 (System.Byte[] bytes) [0x00000] in /Users/tomggg/Desktop/Calivers/Assets/Libs/websocket-sharp/WebSocketFrame.cs:529 
  at WebSocketSharp.Ext+<ReadBytesAsync>c__AnonStorey146.<>m__1B6 (IAsyncResult ar) [0x0002a] in /Users/tomggg/Desktop/Calivers/Assets/Libs/websocket-sharp/Ext.cs:651 

(number of line is maybe not match because I've added code for logging.)

This situation is not so normal because it’s too high pressure(50 message receiving in 1 sec,),, but exists. actually I encountered that.

sta commented 8 years ago

@sassembla Hello there,

Where does your websocket-sharp come from?, and is it used with Unity or not?

So, could you please describe MORE about your environment and represent your repro code?

Thanks for your attempt.

sassembla commented 8 years ago

Thank you for reply!,

I'm using the WebSocketSharp which was downloaded from here (https://github.com/sta/websocket-sharp). Downloaded date is maybe 1~2 weeks ago.

So I'm using Unity for running it. but it is not necessary to reproduce this problem.

I've encountered this problem with

Client: Win10 WebSocketSharp client. (compiled as C# 3.5 app) Server: node.js running at same Win10.

(,,Oh,,! so I bought the WebSocketSharpForUnity before. I forgot to test this case with it.)

sassembla commented 8 years ago

Should I write the repro case with Unity + WebSocketSharpForUnity? or Windows one?

sta commented 8 years ago

Should I write the repro case with Unity + WebSocketSharpForUnity? or Windows one?

Windows one without Unity.

sassembla commented 8 years ago

OK! I'll make it compact then upload. Thank you.

OQO commented 8 years ago

We had same problem on Windows 10 (and Windows 7) with .Net 4.0 and Firefox as client.

We managed to fully fix it by modifying ReadBytesAsync(this Stream stream, int length, Action<byte[]> completed, Action<Exception> error) in Ext.cs. We noticed that 'NetworkStream.EndRead' can return zero (0) bytes even when connection is not being closed. Close reading of documentation of 'EndRead' only says that zero bytes is returned when connection is closed. Other way around is not always true, receiving 0 bytes does not always mean connection is being closed it seems. It is quite common to get zero bytes returned even when the connection is not being closed. Happens once in a while with Chrome, and seems to happen more often with Firefox.

Therefore replacing: if (nread == 0 || nread == length) with: if(nread == length) fixes the problem. It makes sure that when one is waiting for example for the two frame bytes one really gets two bytes back.

Note that there might be other places in the code where the same type of fix might be required based on your usage of this library.

sta commented 8 years ago

@OQO Hello there,

If the connection is really closed, will your fix work?

It is quite common to get zero bytes returned even when the connection is not being closed.

It is very interesting. So, could you please let me know what public .NET documentation does describe about that (zero bytes returned even when the connection is not being closed).

OQO commented 8 years ago

The documentation only says that when the connection is being closed zero bytes is returned. It does not say the opposite: The documentation does not say that when zero bytes are being returned the connection is being closed. https://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.endread%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Note that the documentation does say that it will block until data is available. But it does not says that it will return the data in one time, or even always at least one or more bytes.

The documentation is indeed very unclear. But, we have consistently observed this behavior. The processHeader function (see top of this issue) gives the exception because it receives zero bytes. Adding this fix prevents this.

When the connection is really closed and you still call EndRead it will throw an exception so the reading will end and it is handled. One should probably handle this in a cleaner way by checking the socket state first before calling EndRead.

DoraTong commented 8 years ago

Hi, I had same problem when close connection in OnMessage(). But I use OQO's method to solve but sometime will cause new problem:

2016/11/11 pm 05:40:14|Fatal|<>cDisplayClass17.b16:1848|System.ObjectDisposedException: 無法存取已處置的物件。 物件名稱: 'SslStream'。 at System.Net.Security.SslState.CheckThrow(Boolean authSucessCheck) at System.Net.Security.SslState.get_SecureStream() at System.Net.Security.SslStream.EndRead(IAsyncResult asyncResult) at WebSocketSharp.Ext.<>cDisplayClass9.b8(IAsyncResult ar)

mindryu commented 6 years ago

I had same problem. By the way, the version that is ported to dotnet core 2.0 has no problem. Interesting. https://github.com/ImoutoChan/websocket-sharp-core

z9905080 commented 6 years ago

@AlcoholV your verison is work well on this problem?

"This situation is not so normal because it’s too high pressure(50 message receiving in 1 sec,),, but exists. actually I encountered that."

I had same problem too.

and I test your project can't use WSS connection. -these is my problem.

zaiefenghuo commented 6 years ago

I met the same problem, but I couldn't repeat him. He may always be disconnected from the client. The probability of occurrence is not high. Each occurrence does not trigger the OnError event. The direct websocket service can not continue to run, and the service can only be restarted. I had set "IgnoreExtensions" to true when I started the service, but the problem was not solved.

JohnWinner commented 6 years ago

Same problem. Tried the fix posted by OQO and so far so good. Thank you OQO!

Bitz commented 6 years ago

Same issue here. Tried OQO's fix and it worked; or it seemed to.

When the error would predictably happen, instead of throwing an error and crashing the client connection, it instead ramped up and created a bunch of threads. Hundreds. It eventually calmed back down to the default state.

Avatarchik commented 6 years ago

Has someone gotten a fix? This happens after the client is disconnected ... Every time

zhujinhu21 commented 5 years ago

@JohnWinner what is OQO.

JohnWinner commented 5 years ago

@zhujinhu21 haha it's a username. Scroll up a little bit and you will see him/her giving the fix. ;)

jusoGames commented 5 years ago

Same issue here. Tried OQO's fix and it worked; or it seemed to.

When the error would predictably happen, instead of throwing an error and crashing the client connection, it instead ramped up and created a bunch of threads. Hundreds. It eventually calmed back down to the default state.

did you found a solution to the pile of threads that are created??