c# socket BeginReceive

qq_33368845 2017-09-13 12:16:17
理论上BeginReceive是非堵塞的,然而在实际应用中我发现有时候这个方法也会堵塞,而且是永久性的堵塞。

以下代码在信息不全的判定中出现多次堵死,且每次接收到的字节数都是1440.

void ReceiveEnd(System.IAsyncResult result)
{
SocketError error;
int originL = self.EndReceive(result,out error);
Debug.Log("接收:" +error + originL);
int currentL = 0;
delay = (int)(System.DateTime.Now - sendTime).TotalMilliseconds;
do
{
//包头不全
if (currentL + 4 > originL) { Debug.Log("包头不全:" + originL); ContinueRecieve( currentL, originL - currentL); return; }

//获取包头
int localLength = BitConverter.ToInt32(recive, currentL);
currentL += 4;

//心跳
if (localLength == 0) { Debug.Log("收到心跳回复"); continue; }

//信息不全
if (originL < currentL + localLength) { Debug.Log("信息不全:"+originL+" ->" + currentL); ContinueRecieve( currentL - 4, originL - (currentL - 4)); return; }

byte[] buff = new byte[localLength];
for (int i = 0; i < buff.Length; i++)
buff[i] = recive[i + currentL];
MessageManager.Instance.AddBuff( buff);

currentL += localLength;
} while (currentL < originL);

ContinueRecieve(0, 0);
}

void ContinueRecieve( int copyStart, int copyCount)
{
for (int i = 0; i < copyCount; i++)
recive[i] = recive[copyStart + i];

SocketError error3;
self.BeginReceive(recive, copyCount, recive.Length, SocketFlags.None, out error3, ReceiveEnd, self);
if (error3 != SocketError.Success)
{
Debug.LogWarning(error3 + "持续接收异常 - 可能停止该客户端的网络活动");
return;
}
}
...全文
473 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_33368845 2017-09-14
  • 打赏
  • 举报
回复
这个堵死已经解决了,因为是在unity环境中使用,处于回调里面的bugin引发的错误没有打印出来,表现出了堵死情况。我错误的以为beginrecieve这个方法有堵死的可能性。 感谢你的帮助。 while是在一次性接收到到多个包的时候就行逐个解包。。 我不清楚这个思路是否正确的,目前一次性接到多个包以及半个包时会有极地概率出现错误的包头,包头可能是数亿的长度。
qq_33368845 2017-09-14
  • 打赏
  • 举报
回复
感谢大家的指导,问题已经解决了。
kekezhu0000 2017-09-14
  • 打赏
  • 举报
回复
解析数据包也最好不要用 while 最好是重新开线程处理 ,你应该了解一下IO线程和工作组线程,做真正的异步程序否则效率会很低,多请教一下 "sp1234 " socket这方面他很专业
sdfgrtyu 2017-09-14
  • 打赏
  • 举报
回复
这个太老了,,现在不都是await了
  • 打赏
  • 举报
回复
你所谓的“堵塞”具体是指哪一条语句让线程阻塞呢?请贴出你的调试画面来,说明单步执行到这一条语句之后线程就“堵塞”在这一条语句上了!要么是具体的某条语句,要么就是 while 循环,没有什么其它堵塞的地方了。 如果贴不出堵塞的具体语句,那么你说的堵塞可能就根本不存在,而是你的业务处理有 bug,造成对方不知道何时要继续发送数据过来。
  • 打赏
  • 举报
回复
你的程序基本还是顺序阻塞程序的流程思路。 一个异步程序哪有这么复杂?哪有 while 循环?
  • 打赏
  • 举报
回复
你怎么会写一个 while 循环语句?而且循环里边有 ContinueRecieve、循环外边又有 ContinueRecieve?

110,500

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧