为 BeginReceive 提供的字节
我的程序所做的是,首先连接接受,服务器发送数据 客户端接收然后再次发送(数据大小不变) 服务器接收到它然后再次发回....这个循环继续...
当服务器第二次接收数据时endreceive()返回的int;是 0
虽然我已经找到了解决方案,但我不知道为什么这实际上解决了
我在某处读到的问题,有一个叫做“脏”缓冲区的东西:
所以我所做的是。
//added line
data = new byte[DataSize];
//now index works fine :s
int index = socket.endreceive(result);
以前我重复使用byte[] data
进行发送和接收而不更改其内容,数据发送全为零
并且它有效:)
msdn 没有帮助我,或者我错过了什么? MSDN 链接
这是我提供的 SendCallback 和 Receive Callback 代码的汇总代码
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);
}
}
,您可以看到一个异步命令一次等待一个
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果没有更多数据要接收,并且套接字已关闭(即将没有更多数据要接收),
EndReceive()
返回 0。从您提到的文档中:
通常,您不应该重复使用相同的缓冲区来发送和接收 - 您最终将发送收到的任何数据,并且如果您有重叠的发送和接收异步调用,则可能最终会处于非常奇怪的状态。
只有一次只执行一项操作,并且确保在写入时,您拥有明确设置的确切数据时,“共享”缓冲区才是安全的。
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:
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.