Async Send / Receive

In The Name of God
hello


this is my send and receive asyncronous algorithm: I send the length of algorithm and then actual message.

I have multiple messages to send which they are over and over again, i mean i send user name and them immediately i wanna send password, but the problem is when i wanna receive the password size, Surprisingly i receive the actual password.....and so the size would be something awsome and the program blows....or sometimes in the BegindReceive procedure or anything like this while i have sent data there is no data to peak but i know there is.......this is about 1 month that i got this one, any one can help me out of this morass:

is there any problem with my send and receive functions Please help


Send
-------------------------------------------------------------------
private static bool Special_Send(Socket sck_Socket, byte[] data)
{


//Sending the size

int size_Total = 0;
int size_Size = 4;
int size_Dataleft = size_Size;
int size_Sent = 0;


byte[] size_Container = new byte[4];
size_Container = BitConverter.GetBytes(data.Length);

while( size_Total < size_Size )
{
//i have defined this class at the end of this post: look down, this is for getting the //async function information

AsyncState obj_Size_AsyncState=new AsyncState();
obj_Size_AsyncState.sck_AsyncSocket=sck_Socket;

sck_Socket.BeginSend(size_Container, size_Total, size_Dataleft, 0,new AsyncCallback(Size_Send_Delegate),obj_Size_AsyncState);

size_Total += obj_Size_AsyncState.int_Sent;
size_Dataleft -= obj_Size_AsyncState.int_Sent;
}


//Sending Data

int data_Total = 0;
int data_Size = data.Length;
int data_Dataleft = data_Size;
int data_Sent = 0;

while( data_Total < data_Size )
{
AsyncState obj_Data_AsyncState=new AsyncState();
obj_Data_AsyncState.sck_AsyncSocket=sck_Socket;

sck_Socket.BeginSend(data, data_Total, data_Dataleft, 0,new AsyncCallback(Data_Send_Delegate),obj_Data_AsyncState);

data_Total += obj_Data_AsyncState.int_Sent;
data_Dataleft -= obj_Data_AsyncState.int_Sent;
}

//sck_Socket.Shutdown(SocketShutdown.Both);
//sck_Socket.Close();
return true;
}

-----------------------------------------------------------
Send Asynccallback delegate for Size
------------------------------------------------------------
public static void Size_Send_Delegate(IAsyncResult iar)
{

AsyncState obj_AsyncState=(AsyncState)iar.AsyncState;
obj_AsyncState.int_Sent=obj_AsyncState.sck_AsyncSocket.EndReceive(iar);
}
-----------------------------------------------------------
Send Asynccallback delegate for Data
------------------------------------------------------------
public static void Data_Send_Delegate(IAsyncResult iar)
{

AsyncState obj_AsyncState=(AsyncState)iar.AsyncState;
obj_AsyncState.int_Sent=obj_AsyncState.sck_AsyncSocket.EndReceive(iar);
}

---------------------------------------------------------------------------
Receive
-------------------------------- ---------------------------------------------
private static string Special_Receive(Socket sck_Socket)
{

//Receiving the Size

int size_Total = 0;
int size_Dataleft = 4;
int size_Received = 0;


byte[] size_Container = new byte[4];
while( size_Total < 4 )
{
AsyncState obj_Size_AsyncState=new AsyncState();
obj_Size_AsyncState.sck_AsyncSocket=sck_Socket;

sck_Socket.BeginReceive(size_Container, size_Total, size_Dataleft, 0,new AsyncCallback(Size_Recieve_Delegate),obj_Size_AsyncState);

size_Total += obj_Size_AsyncState.int_Received;
size_Dataleft -= obj_Size_AsyncState.int_Received;
}


int data_Size = BitConverter.ToInt32(size_Container, 0);

//Receiving data

int data_Total = 0;
int data_Dataleft = data_Size;
int data_Received = 0;

byte[] data = new byte[data_Size];

while( data_Total < data_Size )
{
AsyncState obj_Data_AsyncState=new AsyncState();
obj_Data_AsyncState.sck_AsyncSocket=sck_Socket;

sck_Socket.BeginReceive(data, data_Total, data_Dataleft, 0,new AsyncCallback(Data_Receive_Delegate),obj_Data_AsyncState);

data_Total += obj_Data_AsyncState.int_Received;
data_Dataleft -= obj_Data_AsyncState.int_Received;
}
//sck_Socket.Shutdown(SocketShutdown.Both);
//sck_Socket.Close();

return Encoding.ASCII.GetString(data, 0, data_Size);



}

-----------------------------------------------------------
Receive Asynccallback delegate for Size
------------------------------------------------------------
public static void Size_Recieve_Delegate(IAsyncResult iar)
{
AsyncState obj_AsyncState=(AsyncState)iar.AsyncState;
obj_AsyncState.int_Received=obj_AsyncState.sck_AsyncSocket.EndReceive(iar);
}
-----------------------------------------------------------
Receive Asynccallback delegate for Data
------------------------------------------------------------
public static void Data_Receive_Delegate(IAsyncResult iar)
{
AsyncState obj_AsyncState=(AsyncState)iar.AsyncState;
obj_AsyncState.int_Received=obj_AsyncState.sck_AsyncSocket.EndReceive(iar);
}

-----------------------------------------------------------------
and here is the class AsyncState that i use to get the amount byte sent and received:
-----------------------------------------------------------------

class AsyncState
{

public Socket sck_AsyncSocket;

public int int_Sent;
public int int_Received;
}





Answer this question

Async Send / Receive

  • dflAdam

    In TCP there are no message boundaries. I have not read your code
    completely but you need to figure that out yourself. So what this means is that if you send the size and the message that can arrive at the sametime.

    If you want to impose message semantics look at jon cole's blog article

    http://blogs.msdn.com/joncole



  • ShadowedOne

    In The Name of God

    Thanks for your response, the site that u sent me is an approval to my algorithm. i told my program is working with simple Send/Recieve methods, but when i change my algorith and code to be Async so the problem that i posed in the first message appears.

    can u copy and paste the code and use these static methods for just two send/receive communication then u see what i tell u.


  • Hyksos

    My code handles it (see the following).

    if (state.messageSize != 0)
    blah...

    Although, looking at my logic again, I realized that could have made the code more clear by just doing an else statement. If bytesReceived != 4 then message size will always be -1, so the above mentioned line of code is essentially just the else clause but not that obvious. I will fix the code on my blog to be more clear.



  • JonathanEdwards

    In The Name of God

    hello,

    Special Thanks for your response,

    JonCole, I checked that article that u sent for me, that was marvellous and my problem solved.

    for your second post that you pointed out my OBVIOUS problems, those are some stupid problems, i should see weather this would solve that code problem or not.

    but totally thank you, you solved my problem JonCole.


  • SCulver

    I just added a new post to my blog that shows how to do this using the asynchronous code path. Take a look at http://blogs.msdn.com/joncole/archive/2006/04/25/583510.aspx



  • bruno

    I am glad it helped. You may want to re-read the blog entry listed above. I have made a few changes to the text and a couple of minor changes to the code. Some of the updated text contains some issues that you need to keep in mind when using that code. Also, be sure to read all of the comments in the code because I point out a few potential problems that you need to consider in your application.

  • Len Weltman

    On second thought, the way I have it is mostly correct. I need to add code to call the user callback if the message size == 0.

    Basically, we want to decide if we need to post another receive on the socket. There are two cases where we need to do so:

    1) we didn't receive all 4 bytes of the size info
    2) we have received the size info and now need to start reading the body of the message.

    I will update the code on the blog to reflect the handling of the zero length message. It will be an else statement on the "if(state.messageSize != 0)" clause.



  • byronfromwesleyan

    In The Name of God

    hello jonCole,

    in this section:

    if (state.bytesReceived == 4)//we have received the entire message size information

    if the amount of byte received were not 4, which section would handle it

    so its better to modify this if clause like this:

    if( obj_State.int_Received_Bytes == 4 )//we have received the entire message size information
    {
    //read the size of the message
        obj_State.int_Message_Size=BitConverter.ToInt32(obj_State.byt_Buffer, 0);
    if( obj_State.int_Message_Size < 0 )
    {
        throw new ProtocolViolationException("The remote peer sent a                                             negative message size.");
    }
    //we should do some size validation here also (e.g.restrict incoming messages to x bytes long)
    obj_State.byt_Buffer.Initialize();
    obj_State.byt_Buffer = new Byte[obj_State.int_Message_Size];
    //reset the bytes received back to zero because we are now switching //to reading the message body
    obj_State.int_Received_Bytes = 0;
    }
    else
    {
                      obj_State.sck_User_Socket.BeginReceive(obj_State.byt_Buffer,obj_State.int_Received_Bytes, 4-obj_State.int_Received_Bytes, SocketFlags.None, new AsyncCallback(OnReceive), obj_State);
    }


    thanks


  • newone

    I haven't looked over all of your code, but you do have some obvious problems.  For example:

    Inside "Special_Send" you have the following code:

    sck_Socket.BeginSend(size_Container, size_Total, size_Dataleft, 0,new AsyncCallback(Size_Send_Delegate),obj_Size_AsyncState);

    but in that callback function (Size_Send_Delegate) you are using this line of code:

             obj_AsyncState.int_Sent=obj_AsyncState.sck_AsyncSocket.EndReceive(iar);

    You should be calling EndSend instead of EndReceive.  You have the same problem in your Data_Send_Delegate function. 



  • Async Send / Receive