服务器和多客户端通信,当服务器检测到客户端断开连接,如何关闭和客户端通信的子线程

ba_wang_mao 2020-07-24 10:33:35

一、服务器监听客户端时,创建客户端线程时,将线程设置为当主线程退出,自动关闭子线程
Thread th = new Thread(ReceiveMsg);
th.IsBackground = true;
th.Start(tSocket);

二、所有客户端的线程共用下面的方法,ReceiveMsg(object o),只是入口参数不同。
void ReceiveMsg(object o)
{
TcpClient client = o as TcpClient;
while (true)
{
}
}

请问:
1、服务器和【多】客户端通信,当服务器检测到某个客户端断开连接后,服务器如何关闭和该客户端通信的子线程?

2、如果是服务器和【1个】客户端通信,我可以将ReceiveMsg(object o)线程改造成如下形式
bool flag = true;
void ReceiveMsg(object o)
{
TcpClient client = o as TcpClient;
while (flag)
{
}
}

当需要关闭该线程时,只需要将flag=false;即可将该线程关闭。

3、虽然退出主线程系统会自动关闭子程序,由于主线程会长期稳定的运行,客户端工作环境恶劣,会导致客户端不定期的频繁重启建立连接,如果不及时释放丢失了连接的子线程,会在内存中存在大量死线程,占用大量系统资源,不知道我的理解对吗?
...全文
1350 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
ba_wang_mao 2020-07-28
  • 打赏
  • 举报
回复
1、接收线程判断接收长度是否等于0,如果等于0,则客户端下线,关闭TCP连接
     //接收消息
void ReceiveMsg(object o)
{
TcpClient client = o as TcpClient;
while (true)
{
//接收客户端发送过来的数据
try
{
//定义byte数组存放从客户端接收过来的数据
byte[] buffer = new byte[1024 * 1024];
// byte[] Buffer = new byte[1024];
//将接收过来的数据放到buffer中,并返回实际接受数据的长度
int n = client.Client.Receive(buffer);
if (n==0)
{
if (client != null)
{
string point = client.Client.RemoteEndPoint.ToString();
dic.Remove(point);
cboIpPort.Items.Remove(point);

string message = "客户端" + client.Client.RemoteEndPoint.ToString() + "下线啦!";
ShowMsg(message);
client.Close();
}
return;
}
//将字节转换成字符串
//string words = Encoding.UTF8.GetString(buffer, 0, n);
string words = System.Text.Encoding.Default.GetString(buffer, 0, n);
//ShowMsg(client.Client.RemoteEndPoint.ToString() + ":" + words);
ShowMsg(words);


2 、在接收线程的catch (Exception ex)中关闭TCP连接
                 catch (Exception ex)
{
if (client != null)
{
string point = client.Client.RemoteEndPoint.ToString();
dic.Remove(point);
string message = "客户端" + client.Client.RemoteEndPoint.ToString() + "下线啦!";
ShowMsg(message);
client.Close();
}


qq_49636307 2020-07-26
  • 打赏
  • 举报
回复
谢谢分享谢谢分享,学习!
八爻老骥 2020-07-24
  • 打赏
  • 举报
回复
用异步sokect啊,或者用线程池啊。
ba_wang_mao 2020-07-24
  • 打赏
  • 举报
回复
引用 3 楼 wanghui0380 的回复:
前面也跟你说了,你想自己玩,那么扔掉博客园,看msdn的IOCP(IOCP的连接我也不贴了,已经给贴了N遍了,虽然msdn的iocp也差的远,不过好歹总比博客园系列要靠近点)

so:想想看,为啥微软icop要给你建立一个SocketAsyncEventArgs的包装,同时使用异步方法?原因就是你问的
1.俺们不需要什么线程,异步就好
2.不管线程也好,异步也好。既然他是N个不是1个,那么使用上下文对象,做全局管理


大神,你的心意领啦!

任何事情还是要看实际情况,我们公司搞东东特别杂,公司的要求就是要短、平、快,搞任何一项都会出现如下现象:
你搞完这一次,可能十年之内都不会再搞它。

我工作这么多年,搞了太多的东东,但是都集中在嵌入式领域,之前从来都没有接触过C#、JAVA,从来没有在电脑上编写过上位机软件,只学习过《数据结构》、《计算机操作系统》、《UCOSII嵌入式操作系统》、《FreeRTOS 嵌入式操作系统》、《8086/8088汇编语言》、《C51汇编语言》,对现在市面上流行的框架等新知识一窍不通,你提供的那些我看都看不懂,如果没有人教,让我自己搞怎么搞呀!

我的工作不是纯粹的程序员编程,需要了解自动控制系统知识。所以我日常编程学习都是围绕上述工作展开,什么现在先进的知识如果和工作无关,我平时基本不会关注。








wanghui0380 2020-07-24
  • 打赏
  • 举报
回复
前面也跟你说了,你想自己玩,那么扔掉博客园,看msdn的IOCP(IOCP的连接我也不贴了,已经给贴了N遍了,虽然msdn的iocp也差的远,不过好歹总比博客园系列要靠近点) so:想想看,为啥微软icop要给你建立一个SocketAsyncEventArgs的包装,同时使用异步方法?原因就是你问的 1.俺们不需要什么线程,异步就好 2.不管线程也好,异步也好。既然他是N个不是1个,那么使用上下文对象,做全局管理
wanghui0380 2020-07-24
  • 打赏
  • 举报
回复
真是不想回答这类问题了,看博客园系列,劝不动系列 貌似已经劝过你很多遍了,也回复给你N多遍了,“博客园那些东西离一个实际能用玩意,差十万八千里”,你认为那是技术,我们说如果路错了,技术在是技术,也只是一个大坑。你倒是能在填坑的过程里学到技术,不过项目嘛总归是在坑里 好了,反正劝不动,我也不打算劝了 就让你在“坑里”学所谓的高级技术把 while (flag) //既然你说了这个可以,那么就在这里处理,既然你说了一个可以,多个他没有上下文,不知道是那个,那么你就建立和tcpclient关联的上下文
ba_wang_mao 2020-07-24
  • 打赏
  • 举报
回复
引用 14 楼 ying1234 的回复:
做回好人吧,既然楼主说专业不是做这块的,只是公司要求临时用一下,那直接给源码例子比较好。我向同事要了一个supersocket例子的下载连接

http://pan.baidu.com/s/1dFjH6LV 密码 kskr

我下载大概看了看,还比较全,有socket 的服务端,客户端完整例子,有websokcet服务端,客户端完整的例子,socket还是可以跑起来的,其是WindowService 例子里bin/debug/SuperSocket.SocketService.exe ,运行它可以直接选择安装成控制台,还是windowservice,算是挺贴心的例子了。


太感谢啦
ba_wang_mao 2020-07-24
  • 打赏
  • 举报
回复
就用supersocket 搞我的C/S架构程序
ba_wang_mao 2020-07-24
  • 打赏
  • 举报
回复




引用 13 楼 wanghui0380 的回复:
[quote=引用 11 楼 派大奇 的回复:][quote=引用 6 楼 杀马特丶蛮牛 的回复:]有现成的东西,看下supersocket,都给你封装好了
https://www.cnblogs.com/pandefu/p/10774780.html


不错 学习了 省的自己写了[/quote]

这的看他想不想扔掉博客园了,他一个问题重复问了N多遍了,前面已经有无数个人告诉他有supersocket,有dotnetty了[/quote]


应用supersocket 进行持续完善。
ying1234 2020-07-24
  • 打赏
  • 举报
回复
做回好人吧,既然楼主说专业不是做这块的,只是公司要求临时用一下,那直接给源码例子比较好。我向同事要了一个supersocket例子的下载连接 http://pan.baidu.com/s/1dFjH6LV 密码 kskr 我下载大概看了看,还比较全,有socket 的服务端,客户端完整例子,有websokcet服务端,客户端完整的例子,socket还是可以跑起来的,其是WindowService 例子里bin/debug/SuperSocket.SocketService.exe ,运行它可以直接选择安装成控制台,还是windowservice,算是挺贴心的例子了。
wanghui0380 2020-07-24
  • 打赏
  • 举报
回复
引用 11 楼 派大奇 的回复:
[quote=引用 6 楼 杀马特丶蛮牛 的回复:]有现成的东西,看下supersocket,都给你封装好了 https://www.cnblogs.com/pandefu/p/10774780.html
不错 学习了 省的自己写了[/quote] 这的看他想不想扔掉博客园了,他一个问题重复问了N多遍了,前面已经有无数个人告诉他有supersocket,有dotnetty了
ying1234 2020-07-24
  • 打赏
  • 举报
回复
supersocket用过,的确挺不错,稳定,上线运行一年,稳定得快把它忘记了,它的确适合你现在用,不用过多关注底层细节,人家都封装好了。
派大奇 2020-07-24
  • 打赏
  • 举报
回复
引用 6 楼 杀马特丶蛮牛 的回复:
有现成的东西,看下supersocket,都给你封装好了 https://www.cnblogs.com/pandefu/p/10774780.html
不错 学习了 省的自己写了
派大奇 2020-07-24
  • 打赏
  • 举报
回复
引用 8 楼 ba_wang_mao 的回复:
[quote=引用 6 楼 杀马特丶蛮牛 的回复:]有现成的东西,看下supersocket,都给你封装好了 https://www.cnblogs.com/pandefu/p/10774780.html
谢谢! SuperSocket(官方定义:SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架)。 惭愧呀!不知道网上还有这么多好东东! [/quote] 是为了做做 DTU 通讯吗?
ba_wang_mao 2020-07-24
  • 打赏
  • 举报
回复
引用 7 楼 datafansbj 的回复:
什么叫“服务器和所有客户端通信时共用一个方法”?是不是通信时“服务端和客户端公用一个会话连接”?概念有点模糊。

在TCP会话里,任何一端关闭连接,对方都会得到消息,表示会话状态改变了(物理连接中断例外,只能引发超时异常),在处理会话数据的过程中应该自行编写代码处理这种状态变化(即在 While(true) 的代码里必须能够知道何时跳出循环)。


写错啦!
是所有的客户端共用1个接收事件
ba_wang_mao 2020-07-24
  • 打赏
  • 举报
回复
引用 6 楼 杀马特丶蛮牛 的回复:
有现成的东西,看下supersocket,都给你封装好了
https://www.cnblogs.com/pandefu/p/10774780.html


谢谢!
SuperSocket(官方定义:SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架)。

惭愧呀!不知道网上还有这么多好东东!



datafansbj 2020-07-24
  • 打赏
  • 举报
回复
什么叫“服务器和所有客户端通信时共用一个方法”?是不是通信时“服务端和客户端公用一个会话连接”?概念有点模糊。

在TCP会话里,任何一端关闭连接,对方都会得到消息,表示会话状态改变了(物理连接中断例外,只能引发超时异常),在处理会话数据的过程中应该自行编写代码处理这种状态变化(即在 While(true) 的代码里必须能够知道何时跳出循环)。
杀马特丶蛮牛 2020-07-24
  • 打赏
  • 举报
回复
有现成的东西,看下supersocket,都给你封装好了 https://www.cnblogs.com/pandefu/p/10774780.html
ba_wang_mao 2020-07-24
  • 打赏
  • 举报
回复
服务器和【多】客户端通信,由于服务器和所有客户端通信时共用一个方法,当服务器检测到某个客户端断开连接后,服务器如何关联到关闭了连接的客户端并将该客户端通信的子线程关闭呢?
1、本课程是一个干货课程,主要讲解如何封装服务器底层,使用Tcp/ip长连接,IDE使用vs2019 c++开发以及使用c++11的一些标准,跨平台windows和linux,服务器性能高效,单服务器压力测试上万无压力,服务器框架是经历过上线产品的验证,框架简单明了,不熟悉底层封装的人,半个小时就能完全掌握服务器框架上手写业务逻辑。2、本课程是一个底层服务器框架教程,主要是教会学员在windows或linux下如何封装一个高效的,避免踩坑的商业级框架,服务器底层使用初始化即开辟内存的技术,使用内存池,服务器运行期间内存不会溢出,非常稳定,同时服务器使用自定义哈希hashContainer,在处理新的连接,新的数据,新的封包,以及解包,发包,粘包的过程,哈希容器性能非常高效,增、删、查、改永远不会随着连接人数的上升而降低性能,增、删、查、改的复杂度永远都是恒定的O(1)。3、服务器底层封装没有使用任何第三方网络库以及任何第三方插件,自由度非常的高,出了任何BUG,你都有办法去修改,查找问题也非常方便,在windows下使用iocp,linux下使用epoll.4、讲解c++纯客户端,主要用于服务器之间通信,也就是说你想搭建多层结构的服务器服务器服务器之间使用socket通信。还可以使用c++客户端做压力测试,开辟多线程连接服务器,教程提供了压力测试,学员可以自己做压力测试服务器性能。5、赠送ue4和unity3d通信底层框架以及多人交互demo,登录,注册,玩家离开,同步主要是教会学员服务器客户端如何交互。6、赠送c++连接mysql数据库框架demo,登录,注册,玩家离开数据持久化.7、服务器教程使用自定义通信协议,同时也支持protobuf,选择权在开发者自己手里,想用什么协议都可以,自由度高。8、服务器教程使用手动敲代码逐句讲解的方式开展教学课程。非喜勿喷,谢谢大家。9、服务器教程提供源码,大家可以在平台提供的地址下载或者联系我,服务器使用c++11部分标准,std::thread,条件变量,线程锁,智能指针等,需要学员具备一定c++知识,购买前请慎重考虑。

110,556

社区成员

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

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

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