TcpClient多线程下的反复申请与释放导致的内存泄露问题如何解决?

e1ki0lp 2017-01-05 06:34:43
有一个Tcp服务器。
我如果要读服务器,就需要先发送一串数据,然后读取服务器返回的数据。之后服务器会断开连接。
我如果要写服务器,就直接发送一串数据。之后服务器也会断开连接。

也就是每次我读写服务器之后,服务器都会断开连接,下次读写就需要客户端重连。

我现在的方法是写一个类,保存要连接的服务器的IP与端口。
每次读写之前重连服务器,读写完之后断开连接释放TcpClient.
代码大致是最下面那样。

实际应用起来是这样:
先new一个全局的MyClass,在一个循环执行的线程里反复 执行Read 读服务器,当读到某组数据之后,就启动一个新的线程 Write 一次服务器,当然循环Read的线程一直都在执行。
现在的问题是程序跑的时间长了内存就满了。
我只知道是内存溢出了,毕竟反复申请释放,我可能哪里没有释放干净,或者线程锁加的不专业,还请大家指点一下。


public class MyClass
{
private TcpClient tcpClient; // tcp客户端
private IPEndPoint remoteEndPoint; // 保存服务器IP与端口
private object sync = new objecct(); // 线程锁


public MyClass(string ip,int port)
{
tcpClient = new TcpClient(ip,port);
remoteEndPoint = new IPEndPoint(IPAddress.Parse(ip), port);;
}
// 关闭,释放客户端。
public void Close()
{
if (tcpClient != null)
{
tcpClient.GetStream().Close();
if (tcpClient.Client != null)
{
tcpClient.Client.Close();
tcpClient.Client = null;
}
tcpClient.Close();
tcpClient = null;
}
}
// 重新连接服务器
private void Reconnect()
{
Close();
tcpClient = new TcpClient(remoteEndPoint.Address.ToString(), remoteEndPoint.Port);
}
// 读服务器
public byte[] Read(byte[] reg)
{
byte[] buffer=new byte[8192];
lock(sync)
{
Reconnect();
tcpClient.GetStream().Write(reg....
do
{
tcpClient.GetStream().Read(buffer...
}
while (tcpClient.GetStream().DataAvailable);
Close();
}
return buffer;
}
// 写服务器
public void Write(byte[] data)
{
lock(sync)
{
Reconnect();
tcpClient.GetStream().Write(data....
Close();
}
}

}

...全文
641 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
e1ki0lp 2020-12-11
  • 打赏
  • 举报
回复
https://github.com/IOL0ol1/Net.TcpServer
ymj19830801 2020-11-14
  • 打赏
  • 举报
回复
楼主是怎么解决的最后,我也遇到了这个问题
e1ki0lp 2017-01-09
  • 打赏
  • 举报
回复
去掉了close和reconnect方法 直接在read和write里使用 using(tcpClient = new TcpClient()) { // } 来限制tcpClient的作用域 另外还在using外面加了个lock锁 效果还没测,不过好像我发现可能问题主要不是出在这里。
我不懂电脑 2017-01-06
  • 打赏
  • 举报
回复
只是请求应答,不如用webservies
crystal_lz 2017-01-06
  • 打赏
  • 举报
回复
引用 2 楼 diaodiaop 的回复:
既然都是tcp了.为什么要反复的开关开关 这本身就违背了"长连接"的意思了. 按照你目前的意思 你还不如用http呢..反正也是一请求 一相应...何必趟这趟浑水
还有 udp 虽然会丢包
mjp1234airen4385 2017-01-06
  • 打赏
  • 举报
回复
引用 2 楼 diaodiaop 的回复:
既然都是tcp了.为什么要反复的开关开关 这本身就违背了"长连接"的意思了. 按照你目前的意思 你还不如用http呢..反正也是一请求 一相应...何必趟这趟浑水
说的好
by_封爱 版主 2017-01-06
  • 打赏
  • 举报
回复
既然都是tcp了.为什么要反复的开关开关 这本身就违背了"长连接"的意思了. 按照你目前的意思 你还不如用http呢..反正也是一请求 一相应...何必趟这趟浑水
e1ki0lp 2017-01-06
  • 打赏
  • 举报
回复
有的东西不是我想就行的,这是和一个工业机器人通讯的,找人开通的通讯功能。 环境是VmWorkes,C语言编程,需要专门的编译器调用一些专门的函数。编译器和SDK都是收费保密的。 人家就能做成这样,我能怎么办。对我来说它只是软件概念上的TcpServer,我们可以按照对TcpServer的操作方式对机器人里的变量进行读写,但是它并不是一台真正意义上的Server。 有一种东西叫妥协,根据已有的情况综合选择最佳的方案。对于我的应用情景来说,每次读写之前重连,操作完之后断开我认为就是最优实践。 http,udp,websrevies这些根本就不支持。
Poopaye 2017-01-05
  • 打赏
  • 举报
回复
给每个方法开始和结束的地方加个GC.Collect,然后统计下是哪里一直在申请大量的内存

110,533

社区成员

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

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

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