开发者

.NET Async Server receiving data for no apparent reason

I am totally confused right now.

Edit: Okay, nevermind. The Python socket as well is starting to do it now.

Edit 2: Well, not quite sure if this is causing high CPU usage, but something randomly is. Is there an efficient way to figure out what is causing spikes in the usage? This project is a bit large and has various threads.

I have an asynchronous server that listens and waits for incoming connections, then keeps them alive and waits for the socket to flush and give the server data. It is only closed when the user wants the socket to be closed.

However, whenever I let a socket & stream stay connected, it starts to go haywire and starts sending empty data on an endless loop... it may take anywhere from 15 seconds to over a minute before it starts going wack. If I let it go for a really long time, it starts to cause really high CPU usage.

Aside from the high CPU usage, oddly enough, everything works as it should; messages are sent & received fine.

This is my read callback function:

    protected void ReadCallback(IAsyncResult ar)
    {
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.SocketHandle;

        try
        {
            int bytesRead = (state.BytesRead += handler.EndReceive(ar)), offset = 0;
            string line = m_Encoder.GetString(state.Buffer, 0, bytesRead);
            if ( state.Buddy != null )
                Console.WriteLine(state.Buddy.Address);
            if (bytesRead > 0)
            {
                Console.WriteLine("!!!");
                /* A complete request? */
                if (line.EndsWith("\n") || line.EndsWith("\x00"))
                {
                    string[] lines = line.Split('\n'); // ... *facepalm*
                    foreach (string ln in lines)
                        this.MessageReceieved(ln, state);

                    state.Buffer = new byte[StateObject.BUFFER_SIZE];
                    state.BytesRead = 0; // reset
                }
                /* Incomplete; resize the array to accommodate more data... */
                else
                {
                    offset = bytesRead;
                    Array.Resize<byte>(ref state.Buffer, bytesRead + StateObject.BUFFER_SIZE);
                }
            }
            if (handler != null && handler.Connected )
                handler.BeginReceive(state.Buffer, offset, state.Buffer.Length - offset, SocketFlags.None, new AsyncCallback(ReadCallback), state);

        }
        catch (SocketException)
        {
            if (state.Buddy != null)
                state.Buddy.Kill();
            else
                handler.Close();
        }
    }开发者_开发问答

I know this is somehow caused by calling BeginReceive, but I don't know how else to keep the connection alive.


There is nothing in that code that can make it go haywire.

I do see some problems though.

Connection detection

No need to check if the socket is connected. You can detect disconnections in two ways in the receive callback:

  1. Zero bytes is returned by EndReceive
  2. An exception is being thrown.

I would recommend that the first thing you do after EndReceive is to check the return value and handle disconnect accordingly. It makes the code clearer.

Your code will currently do nothing if 0 bytes are received. The handler will just stop receiving and still think that the connection is open.

Buffer handling

Your buffer handling is very inneffecient. Do not resize the buffer every time. It will slow your server down a lot. Allocate a large buffer from start.

String handling

Don't build a string every time you receive something. Check inside the byte buffer after new line or null instead. THEN build a string, and only make it as large as needed. You might receive more bytes that just a message (for instance one and a half message)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜