很奇怪的问题!异步通讯中连接上后一段时间不发送数据再次发送接收不到数据的问题

zsww222 2017-02-21 10:03:30
软件采用异步方式进行通讯,正常情况下连接,发送/接收数据都是正常的

但碰到一个很奇怪的情况,就是当服务端和客户端A在已连接的情况下,如果有十几分钟或更长时间双方没有发送接收任何数据,
然后客户端A再次发送数据给服务端的话,服务端就接收不到了???
但更奇怪的是,如果另一个客户端B连接上服务端的时候,并发送数据给服务端后,好像又激活了服务端,然后这两个客户端分别收到了服务端发送过来各自对应的响应数据

难道异步通信中长时间不发送/接收数据会阻塞吗?代码如下,请兄弟姐妹们帮我分析下到底是什么原因造成的,万分感谢!!


//服务端

private Socket _sockSvr;
private const int _buffersize = 2048;
private DataStruct m_DpObj = null;//DataStruct 是个自定义的类

public class DataStruct
{
public Socket ClientSocket = null;
public string ID = string.Empty;
public byte[] RecvData = new byte[2048];
public int nReadBytesNums = 0;
}

public int Start()
{
StartListen();

_sockSvr.BeginAccept(new AsyncCallback(AcceptCallBack), _sockSvr);

return 1;
}

private void StartListen()
{
_sockSvr = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint iep = new IPEndPoint(IPAddress.Any, Port);
_sockSvr.Bind(iep);

_sockSvr.Listen(10);
}

private void AcceptCallBack(IAsyncResult ar)
{
Socket handler = (Socket)ar.AsyncState;
Socket _clientSock = handler.EndAccept(ar);

m_DpObj = new DataStruct ();
m_DpObj.ClientSocket = _clientSock;
m_DpObj.ID = GetClientIp(_clientSock);

_clientSock.BeginReceive(m_DpObj.RecvData, 0, _buffersize, SocketFlags.None, new AsyncCallback(ReceiveData), m_DpObj);
_sockSvr.BeginAccept(new AsyncCallback(AcceptCallBack), _sockSvr);
}

private void ReceiveData(IAsyncResult ar)
{
DataStruct ds= ar.AsyncState as DataStruct ;
Socket tempsocket = ds.ClientSocket;
ds.nReadBytesNums = ds.ClientSocket.EndReceive(ar);

if (ds.nReadBytesNums > 0)
{
//流程处理,忽略
}

ds= new DataStruct ();
ds.ClientSocket = tempsocket;

tempsocket.BeginReceive(ds.RecvData, 0, _buffersize, SocketFlags.None, new AsyncCallback(ReceiveData), ds);
Thread.Sleep(5);
}

...全文
344 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
飞天凤凰601 2017-02-22
  • 打赏
  • 举报
回复
看你的描述,没有设置心跳包 搞心跳包就应该不会出问题 了
  • 打赏
  • 举报
回复
另外,就你的代码来说,所谓“流程处理,忽略”这里占用了 I/O 时间,是不好的。你或者把 tempsocket.BeginReceive... 语句放到他的前边(Sleep 5 是干什么的,你还要故意延迟程序执行?),或者把它异步处理而不要拖延 I/O。
  • 打赏
  • 举报
回复
记录个日志(或者在 Debug.Print 打印日志),看看到底是 ds.nReadBytesNums = ds.ClientSocket.EndReceive(ar) 语句根本没执行,还是只是你的“流程处理,忽略”里边有问题。 把日志推送到具体的语句上,指明具体语言问题。不要自己根据“现象”拍着脑袋(而不动手),一叶障目。
zsww222 2017-02-22
  • 打赏
  • 举报
回复
如果有心跳维持就不会出现这个情况,就是在只连接但无任何交互的时候出现这个情况
zsww222 2017-02-22
  • 打赏
  • 举报
回复
引用 1 楼 xian_wwq 的回复:
“客户端A再次发送数据给服务端的话,服务端就接收不到了”, 难道没有报错信息? 一般来说,如果数据量小,实时性要求低,不需要维持长连接,用完后就释放; 如果要维持长链路,如果数据实时性较低, 客户端就得有心跳机制来保证链路的活跃度 否则,即使server端没有超时清理, 好多网络设备也会自动清理非活跃的链路
没有异常,感觉socket还是维持连着的状态,因为终端始终也没断,只是发送消息给服务端服务端没有任何响应,但另一个客户端连接上后,好像服务端又被激活了一样,把要应答之前那个客户端的消息发出去了,给人的感觉像是BeginReceive被阻塞了一样
xian_wwq 2017-02-22
  • 打赏
  • 举报
回复
“客户端A再次发送数据给服务端的话,服务端就接收不到了”, 难道没有报错信息? 一般来说,如果数据量小,实时性要求低,不需要维持长连接,用完后就释放; 如果要维持长链路,如果数据实时性较低, 客户端就得有心跳机制来保证链路的活跃度 否则,即使server端没有超时清理, 好多网络设备也会自动清理非活跃的链路
内容概要:本文系统研究了基于CNN-SVM的卷积神经网络与支持向量机融合的数据分类预测方法,聚焦其在工业故障识别的应用,提供了完整的Matlab代码实现。通过CNN提取输入数据的深层空间特征,再由SVM进行高精度分类,充分发挥两者优势,有效提升了故障识别的准确性、鲁棒性与泛化能力。该方法特别适用于处理电力系统、机械设备等领域的高维、非线性、强噪声监测数据,在变压器故障诊断、轴承缺陷识别等场景具有重要应用价值。文档还整合了机器学习、深度学习、图像处理、路径规划、电力系统优化等多个前沿科研方向的技术资源,配套大量Matlab/Simulink仿真案例与Python代码,全面支持科研复现与工程实践。; 适合人群:具备一定编程基础,熟练掌握Matlab或Python语言,从事电气工程、自动化、人工智能、机械故障诊断等相关领域研究的研发人员及高校研究生; 使用场景及目标:① 实现工业设备的状态监测与多类别故障分类;② 深入理解CNN与SVM融合模型的设计原理与工程实现细节;③ 借助所提供的丰富算法案例开展科研复现、模型优化与系统仿真验证; 阅读建议:建议按照文档目录结构系统化学习,结合百度网盘提供的完整代码资源进行动手实践,重点关注CNN特征提取层与SVM分类器之间的数据接口设计与参数调优策略,同时可延伸学习文涉及的其他智能算法及其在电力系统、信号处理等领域的交叉应用,全面提升科研创新能力。

111,129

社区成员

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

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

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