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");
开发者_如何学JAVA 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
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.
精彩评论