Runtime: SocketAsyncEventArgs Receive data errors

Created on 2 Dec 2018  Â·  24Comments  Â·  Source: dotnet/runtime

I use SocketAsyncEventArgs pool to receive data in sockets, with bombarding testing and web browser access.
Turn off the bombarding tool and use only the web browser access the received data error, debug receive data:

bombarding test url:'/customers?count=1'
web browser test url:'/employees'
system:ubuntu 16.04 64
dotcore version:2.14,2.15
SocketAsyncEventArgs setbuffer code

#if (NETSTANDARD2_0)
            this.SetBuffer(0, length);
#else
            this.SetBuffer(BufferX.Memory.Slice(0, length));
#endif
area-System.Net.Sockets bug needs more info os-linux

Most helpful comment

@IKende, I don't mean to be nit-picky, but what you shared is compiled binaries and isn't a small, isolated repro. What I'm hoping to see from you is a small, compilable, standalone piece of C# code that demonstrates the problem, that we can review, run, debug, etc.

All 24 comments

Can you please share an isolated repro of the issue you're seeing? It's not clear what the problem is from your description, nor whether it's actually a problem in .NET Core or in your own code.

```c#
public class SocketAsyncEventArgsX : SocketAsyncEventArgs
{
public SocketAsyncEventArgsX ()
{
SetBuffer(new byte[10248],0,10248);
}
public bool IsReceive
{
get;
set;
}

    public ISession Session { get; internal set; }

    public void AsyncFrom(System.Net.Sockets.Socket socket, object useToken, int size)
    {
        this.IsReceive = true;
        this.UserToken = useToken;
        this.SetBuffer(0, size);
        if (!socket.ReceiveAsync(this))
        {
              OnCompleted(this)
        }
    }
    public void AsyncFrom(ISession session, object useToken, int size)
    {
        this.Session = session;
        AsyncFrom(session.Socket, useToken, size);
    }
    public void AsyncTo(System.Net.Sockets.Socket socket, object userToken, int length)
    {
        this.SetBuffer( 0, length);        
        this.UserToken= userToken;
        if (!socket.SendAsync(this))
        {      
            OnCompleted(this)
        }
     }
    public void AsyncTo(ISession session, object userToken, int length)
    {
        this.Session = session;
        AsyncTo(Session.Socket, userToken, length);
    }
}
Working with Code:
```c#
var saeax = saeapool.pop();
saeax.AsyndFrom(socket);

after complete
c# saeapool.Push(saeax);
Turn off the test tool after a long period of time using tool performance testing,use other tools to send different data,currently received is the data sent by the previous tool。The problem has been repeated many times.
not use the SocketAsyncEventArgs pool, each socket is used alone SocketAsyncEventArgs , didn't see the problem.

Thanks, but can you please share something that's actually runnable that repros the problem you're seeing?

https://github.com/IKende/FastHttpApi/blob/master/saeabugtest.zip
This is the program that tests the problem.
run program to ubuntu 16.04

dotnet HttpApiServer.DataServer.dll

Turn off the test tool after a long period of time using tool performance testing url 'http://ip:9090//customers?count=2'
then only using web browser access url'http://ip:9090//employees'

@IKende Does this issue occurs on Windows?

We need to verify the repro on Ubuntu first. The verification should target 3.0 as this issue sounds scary - SocketAsyncEventArgs pool mixed up data in Sockets.

@karelz

I tested it on Ubuntu, not known if windows also has such this problem

change code not use SocketAsyncEventArgs pool, each socket is used alone SocketAsyncEventArgs.
tested for two days didn't see this problem

@IKende, I don't mean to be nit-picky, but what you shared is compiled binaries and isn't a small, isolated repro. What I'm hoping to see from you is a small, compilable, standalone piece of C# code that demonstrates the problem, that we can review, run, debug, etc.

ok i tried to write a simple code to test the problem.

Thank you.

I have to say that I met the same problem a month ago and I also posted an issue (https://github.com/dotnet/corefx/issues/33246), which is closed now. I fixed it by uninstalling and reinstalling dotnet core runtime for several times. I thought it was a bug of orlean's compatibility to some specific version of dotnet core runtime. But now it looks like it's not a bug of orleans.

The problem I met is when the Buffer of a AsyncSocketEventArgs is reused between different sockets, the newly accepted socket will still getting the content of the old buffer, even calling args.SetBuffer(0, args.Buffer) doesn't work.

The issue that I posted in orleans project is this one: https://github.com/dotnet/orleans/issues/5160

simple code

Thank you for the code. What symptoms should I be looking for to see the bug? It's not clear to me from the screenshots / arrows in the screenshots. The code also doesn't appear to be making any client requests, nor asserting when it gets something unexpected. I don't know what to do with this to see the problem.

the code is a simple HTTP server that responds back to the contents of the request. the web browser request agent content should not be fasthttp ,agent content fasthttp from the bombardier.exe tool request.

run the code on Ubuntu 16.04. host[http://ipaddress:9090]
Turn off the bombardier.exe tool after a long period of time using tool performance testing then use only the web browser access server。

At this point, the content requested by the Web browser becomes the contents of the bombardier.exe tool request

Is there any solution for this issue? I tryead all versions of net core from 2.0 to 2.2 but this bug still occures :(

@radmikulka, can you share a small repro? I was not able to reproduce with what @IKende previously shared.

my solution dislabed SocketAsyncEventArgs pool:(

@IKende @radmikulka do you have a repro or are you able to reproduce it at least on your end and help us with investigation?
Otherwise I fear we cannot make progress :(

https://github.com/IKende/BeetleX/blob/master/SaeaPoolTest.zip download this code run in ubuntu 16.04
running bombardier tool

bombardier.exe -c 200 -n 20000000 http://[ubuntu IPAddress]:9090/

Open browser access http://[ubuntu IPAddress]]:9090/ when the bombardier finished running,
the response content obtained by the browser is the request content of the bombardier

I'll check if I can reproduce it @stephentoub

Thanks, @wfurt.

I have setup as described but I was not able to reproduce this so far. I tried to run bombardier tool several times and than access it from Safari and curl. I also added bool bombardier = requestText.StartsWith("GET / HTTP"); and I dump more debug when accessing x.x.x.x/test url.
I have 16.04.6 on 4 core VM.

We cannot reproduce it, no activity for 1.5 months, closing.
If you have more details, please let us know and we can reopen.

attention

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bencz picture bencz  Â·  3Comments

jchannon picture jchannon  Â·  3Comments

jamesqo picture jamesqo  Â·  3Comments

EgorBo picture EgorBo  Â·  3Comments

GitAntoinee picture GitAntoinee  Â·  3Comments