Sign in to follow this  
Thevenin

faFEHf 2!$!@%@!% (.NET Socket problems)

Recommended Posts

I've been stabbing at this problem for months now, and I still can't figure it out. Whenver someone goes up and down a staircase in my game in rapid succession, their TCPBuffer gets a few bytes zeroed which causes one of three fatal exceptions. It can't (can) be the server because I noticed during one crash, the 'short' datatype in the TCPBuffer that represented the size of the packet that was being readin was zero (No matter how badly the data on the server is, the packet size constant will never be zero!). I've outputted all the sizes of packets the client read in before the crash, and they were all normal values (eg.. its not the case of the server sending a packet with the wrong size, thus causing the shiftTCPBuffer() function to go hay-wire on the buffer). The client's sShiftTCPBuffer command looks like this (Where TheStackSize = constant int = 1000).
    public void sShiftTCPBuffer()
    {
        /*
         * Name: sShiftTCPBuffer
         * Programmer: Peter Blain.
         * Version: January 7, 2006.
         * Description: This procedure shifts the user's TCP buffer back by a specified number
         *              bytes; for use with reading packets.
        */

        /* Get the number of bytes that the buffer needs to be shifted. */
        short TheNumberOfBytes = BitConverter.ToInt16(TheTCPBuffer, 1);

        TheDisplay += TheNumberOfBytes.ToString() + "\n";

        /* Shift and clear the TCP stack. */
        Array.Copy(TheTCPBuffer, TheNumberOfBytes,
                   TheTCPBuffer, 0, TheTCPStackSize - TheNumberOfBytes);
        Array.Clear(TheTCPBuffer, (TheTCPStackSize - 1) - TheNumberOfBytes, TheNumberOfBytes);

        /* Now decrement the TCP stack. */
        TheTCPOffset -= TheNumberOfBytes;

        if (BitConverter.ToInt16(TheTCPBuffer, 1) == 0 &&
           TheTCPOffset >= 3) throw new Exception("!??!?!333");
    }
The server's send packet function looks like this..
    public void sSendPacket(byte[] TheData, int TheClient)
    {
        /* 
         * Name: sSendPacket
         * Programmer: Peter Blain.
         * Version: Janurary 7, 2006.
         * Description: This procedure sends the given data packet to the specified client, via
         *              its connection.
        */

        MyPlayerStats[TheClient].ThePacketsSent++;
        try
        {
            if (TheClients[TheClient].MySocket.Send(TheData, 0, TheData.Length, SocketFlags.None) !=
                TheData.Length)
            {
                throw new Exception("Could not send all data to user.");
            }
        }
        catch (SocketException)
        {
            sDisconnect(TheClient, null);
        }
    }
.. and no.. sDisconnect() doesn't get called during a crash. The error is in the client itself. The client's recieve command.
    public void sCheckReceive()
    {
        /* 
         * Name: sCheckReceive
         * Programmer: Peter Blain.
         * Version: July 17, 2006.
         * Description: This procedure checks if there is data coming from the socket. If so
         *              it recieves the data and then calls a check for complete packets.
        */

        try 
        {
            if (MyGlobalSocket.Poll(0, SelectMode.SelectRead))
            {
                int TheBytesRead = MyGlobalSocket.Receive(TheTCPBuffer, TheTCPOffset, TheTCPStackSize - TheTCPOffset, SocketFlags.None);

                /* Increment the TCP offset. */
                TheTCPOffset += TheBytesRead;

                /* Before starting the recieve function again, lets check if we have any
                 * complete packets. */
                sCheckForCompletePackets();
            }
        } 
        catch (Exception e)
        {
            MessageBox.Show(e.ToString(), "Fleurin - Socket Recieve error.");
            Application.Exit();
        }
    }
and lastly... the check for complete packets().
    public void sCheckForCompletePackets()
    {
        /* 
         * Name: sCheckForCompletePacket
         * Programmer: Peter Blain.
         * Version: January 6, 2006.
         * Description: This procedure checks if a complete packet has been recieved.
        */

        while (TheTCPOffset >= 3)
        {
            /* Check if the size of the packet being recieved has been
             * completly recieved. */
            short ThePacketSize = BitConverter.ToInt16(TheTCPBuffer, 1);
            if (ThePacketSize == 0) throw new Exception("!?!?!?!");
            if (TheTCPOffset >= ThePacketSize)
            {
                switch (TheTCPBuffer[0])
                {
                    /* Packet: User is requesting to spawn. */
                    case (byte)FleurinFlags.EServerSend.SpawnPacket:
                        sPakReadSpawn();
                        sShiftTCPBuffer();
                        TheProgramLocation = EProgramLocation.InGame;
                        break;

                    case (byte)FleurinFlags.EServerSend.PopUp:
                        sPakReadPopUp();
                        sShiftTCPBuffer();
                        break;

                    case (byte)FleurinFlags.EServerSend.Inventory:
                        sPakReadInventory();
                        sShiftTCPBuffer();
                        break;

                    case (byte)FleurinFlags.EServerSend.Movement:
                        sPakReadMovement();
                        sShiftTCPBuffer();
                        break;

                    case (byte)FleurinFlags.EServerSend.Player:
                        sPakReadPlayer();
                        sShiftTCPBuffer();
                        break;

                    case (byte)FleurinFlags.EServerSend.Costume:
                        sPakReadCostume();
                        sShiftTCPBuffer();
                        break;

                    case (byte)FleurinFlags.EServerSend.Message:
                        sPakReadMessage();
                        sShiftTCPBuffer();
                        break;

                    case (byte)FleurinFlags.EServerSend.Direction:
                        sPakReadDirection();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.Flush:
                        sPakReadFlush();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.Monster:
                        sPakReadMonster();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.PoofEffect:
                        sPakReadPoof();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.NumberEffect:
                        sPakReadXP();
                        sShiftTCPBuffer();
                        break;
                    case(byte)FleurinFlags.EServerSend.Health:
                        sPakReadHealth();
                        sShiftTCPBuffer();
                        break;
                    case(byte)FleurinFlags.EServerSend.Item:
                        sPakReadItem();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.Skill:
                        sPakReadSkill();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.Spell:
                        sPakReadSpell();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.Mana:
                        sPakReadMana();
                        sShiftTCPBuffer();
                        break;
                    case (byte)FleurinFlags.EServerSend.Projectile:
                        sPakReadProjectile();
                        sShiftTCPBuffer();
                        break;
                    /* Packet: Corrupted. */
                    default:
                        throw new Exception("Corrupted TCP buffer detected; you've been dictated out.");
                }
            }
            else
            { break; }
        }
    }
HALP! [depressed]

Share this post


Link to post
Share on other sites
Anything guys, just yell out anything!

I've searched this code a hundred times, I'm running completly out of ideas as to where the error is. >.<

Share this post


Link to post
Share on other sites
it only happens when you use stairs right? does it always happen after the same number of stairwalks? Which functions get called when you walk a stair up/down?

btw. Hope you fix it soon,i wanna play

regards,
m4gnus

Share this post


Link to post
Share on other sites
I think I've found the error.

The TCP stack size is only 1KB. When you go down a staircase, you may recieve a couple KBs worth of data, since it has to send you flush packets for all the monsters above the ground, and packets for all items and monsters below. Inaddition, some catch{} statement could be muzzling the error that the .NET socket code SHOULD HAVE THROWN ([flaming]) or it could be that my parametesr to the buffer upper limit is off by 1.

I increased the stack size to 10KB and now no matter how much I provoke the code, I can't seem to get any errors.

I'm on such an emotional 'high' right now (for having solved this), that if the error pops up again, I'm gonna cry all night.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this