views:

32

answers:

1

what my program does is, At first connection accept, server sends data the client receive then sends again (Datasize does not change) Server receives it then sends back again .... this loop continues ...

when the second time the server receives data the int returned by endreceive(); is 0

although i have found the solution but i dont know why does this actually solve the problem

i read somehewhere that there is something called 'dirty' buffer :s

so what i did was.

//added line
data = new byte[DataSize];

//now index works fine :s
int index = socket.endreceive(result);

previously i was reusing byte[] data for send and receive without changing its contents, data send is all zeros

and it worked :)

msdn doesnt help me there or have i missed somwthing ? MSDN Link

This is the summarized code

    private void OnSendCallBack(IAsyncResult result)
    {
        int id_client = (int)result.AsyncState;
        try
        {

            int index = clientInfo[id_client].client.EndSend(result);

            clientInfo[id_client].offsetSend += index;
            if (index == 0)
            {
                Console.WriteLine("Index == 0");
                return;
            }
            else if (clientInfo[id_client].offsetSend < DataSize)
            {
                clientInfo[id_client].dataToSend = DataSize - clientInfo[id_client].offsetSend;
                clientInfo[id_client].client.BeginSend(data, clientInfo[id_client].offsetSend, clientInfo[id_client].dataToSend, SocketFlags.None, RecieveCallBack, id_client);
            }
            else 
            {
                clientInfo[id_client].offsetSend = 0;
                clientInfo[id_client].dataToSend = DataSize;
                //*************************************
                data = new byte[DataSize]; // THIS IS THE PROBLEM HERE
                //*************************************
                clientInfo[id_client].client.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallBack, id_client);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Send: " + ex.Message);
        }
    }

private void RecieveCallBack(IAsyncResult result)
    {
        int id_client = (int)result.AsyncState;

        try
        {

            int index = clientInfo[id_client].client.EndReceive(result);

            //byte[] buffer = new byte[DataSize];
            //int received = clientInfo[id_client].client.Receive(buffer);

            clientInfo[id_client].offsetRec += index;
            if (index == 0)
            {
                index = clientInfo[id_client].client.EndReceive(result);
                Console.WriteLine("Index == 0");
                return;
            }
            else if (clientInfo[id_client].offsetRec < DataSize && clientInfo[id_client].offsetRec != 0)
            {
                clientInfo[id_client].dataToReceive = DataSize - clientInfo[id_client].offsetRec;
                clientInfo[id_client].client.BeginReceive(data, clientInfo[id_client].offsetRec, clientInfo[id_client].dataToReceive, SocketFlags.None, RecieveCallBack, id_client);
            }
            else
            {
                clientInfo[id_client].offsetRec = 0;
                clientInfo[id_client].dataToReceive = DataSize;

                if (clientInfo[id_client].RunNumber < RounCount)
                {
                    clientInfo[id_client].RoundTripStat.EndSample();
                    clientInfo[id_client].RoundTripStat.BeginSample(); 
                    clientInfo[id_client].client.BeginSend(data, 0, data.Length, SocketFlags.None, OnSendCallBack, id_client); 
                }

                Close(id_client);
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("Server: " + ex.Message);
        }
    }

I have provided code of SendCallback and Receive Callback, as you can see one asynch command is waiting one at a time

+1  A: 

EndReceive() returns 0 if there was no more data to receive, and the socket has been closed (i.e. there will be no more data to receive).

From the docs you referred to:

If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the EndReceive method will complete immediately and return zero bytes.

You shouldn't generally reuse the same buffer for both sending and receiving - you'll end up sending whatever data you received, and if you have overlapping send and receive asynchronous calls it'll end up in a very strange state, potentially.

It's only safe to "share" the buffer if you only ever perform one operation at a time, and you make sure that when you write, you have exactly the data you want, explicitly set there.

Jon Skeet
yes, i am performing one operation at a time, but, before receiving if i don't do data=new byte[DataSize] ... i receive 0 from EndReceive(...) and the socket flag; 'Connected' automatically gets set to false :s
KiNGPiN
@KiNGPiN: That sounds extremely strange - are you sure it's not because you were sending incorrect data? A short but complete program demonstrating the problem would really help here.
Jon Skeet
i have updated the question with code snippet, as you can see in SendCallBack i start the BeginReceive ... send is only called back again once data has receivedand the code is simple no data manipulation whatsoever
KiNGPiN