vb.net socket编程,多个客户端长连接一个服务端的问题

hbhuo2008 2019-03-06 03:35:13
因设备升级原串口传输改为网络传输,需开发一个程序来控制设备并接收设备发来的数据。
设备为客户端并有4个,程序为服务端,
任何客户端状态的变化服务端多要记录下来,
服务端接收数据并可以随时控制客户端。
使用socket编程。
目前的问题是4个客户端长连接服务端,服务端如何判断连接的客户端实时在线?
服务端连接多个客户端 如何向一个客户端发送数据?
...全文
535 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
hbhuo2008 2019-03-13
  • 打赏
  • 举报
回复
谢谢各位大侠的帮助

嗯,还是用定时向客户端发送数据方法 确定是否在线。
  • 打赏
  • 举报
回复
在传统的短链接、特别是 http 机制的连接中,花费巨大代价去搞低效率的心跳(而不是高效率的长连接心跳)机制,其实就是因为短链接——每一次通讯都需要执行复杂的握手协议过程——而造成的,此时服务器没办法连接客户端。 现在是长连接,可以说效率提升了成千上万倍,服务器做点有关推送、探测的事儿是举手之劳。不要当成什么“技术”,纯粹是自己还在用短链接的思维概念来编程造成的。
  • 打赏
  • 举报
回复
这里唯一重要的“技术问题”就是,所谓 Connected 状态所反映的是最后一次发送或者接受数据时是否成功,当没有收发动做时实不会改变状态的,所以你看不到状态改变。如果要确保获得最新状态,那么就要如#1楼所说要做一个“检测”设计。但是不同的是,无需由客户端去访问服务器,也无需服务器回复心跳包。因为是长连接,所以服务器随便发送一个字节、0个字节,并且无需回复,就能知道客户端是否在线。
  • 打赏
  • 举报
回复
长连接,客户端可以随时发信息给服务器端,服务器端也可以随时发信息给客户端。比如说你们的协议中规定“空白”信息是无需回复的,或者随便选一个最简洁最无“实际意义”的信令,服务器定时发一下就行了,就能保证经常维护 Connected 状态了。 写 c# 代码也就是2行代码(一个 foreach 和一个 Send 语句),所以这不是什么大事儿,关键是有没有正确的基本概念。
wanghui0380 2019-03-08
  • 打赏
  • 举报
回复
换成简单点方式吧。虽然内部机制你可以了解,甚至没事情干的时候可以自己研究

做项目还是快速解决先。服务器装个etcd,客户端代码启动自己去etcd更新信息(后面的状态也好,其他信息也好,有变动自己更新etcd)

服务端监听etcd节点,自己判定是状态更新,还是心跳缓存超时。

类似etcd的东西还有很多,比如consul ,zoopkeep
其实原理上大家都差不多的--都是服务发现,服务注册,服务健康状态,服务操作(webapi/tcp),高可用群集,公用信息同步这类

我们可以自己研究那些单项原理,不过项目上如果有可以用的轮子,还是先用轮子,如果业务发展了轮子不和用了,自己在折腾自己的(阿里也好,百度也罢,啥推特,netfix基本也都是这路子,先用现成的,规模大了不和用了,在改造自己的)
  • 打赏
  • 举报
回复
引用 3 楼 hbhuo2008 的回复:
另外客户端无法掌控,是设备无法配置向服务端发送心跳包。
客户端不会发信息,既然你是长连接机制,服务器断不会主动发个0字节或者比较简洁的信息吗?
  • 打赏
  • 举报
回复
服务器对于客户端如果没有收发动做,怎么会改变 Connected 状态呢?
  • 打赏
  • 举报
回复
我至今没有作过只写或者只读的通讯程序。总归——凭感觉——也该每隔几分钟随便发个心跳字节。
吹风的兔子 2019-03-08
  • 打赏
  • 举报
回复
印象中,长链接的 的 Socket 如果 长时间不通讯、或者 长时间 单向通讯 Socket 连接 可能会断。 Socket 本身是没有这个BUG的。 但是 大部分路由器、网关 会每隔 5 ~10 分钟,将路由表中 没有发出数据(还是没有接收数据) 的 连接关闭。 所以:最原始的 Socket 心跳包 大部分都是:一个请求、一个响应 —— 同时在进行上下行操作。 2010年,遇到这种 上下行的心跳包,当时我就在想:只发送不就行了,干嘛要接收 (反正发送失败就表示断线) 后来在实际项目中,发现:有上下行心跳包的 Socket 更稳定。
hbhuo2008 2019-03-07
  • 打赏
  • 举报
回复
引用 1 楼 黄富国 的回复:
1,每个socket 都会有相对应的RemoteEndPoint , 你用dect 在socket 第一次连接时保存socket的RemoteEndPoint 作为用户的标记
2,使用心跳机制去判断用户是否在线, 每个一定时间客户端向服务器发送心跳包,再回应客户端, 双方记录心跳时间,如果大于心跳时间则判断为掉线


你好,我对socket编程还不熟悉,dect具体什么用?
我是用一个数组保存连接的用户,但有时候会重复。
另外客户端无法掌控,是设备无法配置向服务端发送心跳包。
昨天试了两个办法都无法判断。(connected和poll)
 For i = 0 To lstClient.Count - 1

If lstClient.Item(i).Connected = True Then
TextBox4.AppendText(vbCrLf & lstClient.Item(i).RemoteEndPoint.ToString)

End If

If lstClient.Item(i).Poll(10, SelectMode.SelectRead) = True Then
MessageBox.Show("客户端已断开或关闭。", "提示", MessageBoxButtons.OK)
lstClient.Remove(lstClient.Item(i))
Else
TextBox4.AppendText(vbCrLf & lstClient.Item(i).RemoteEndPoint.ToString)
End If
Next

黄富国 2019-03-06
  • 打赏
  • 举报
回复
漏了一句,通过RemoteEndPoint ,可以把数据发到用户,如果想更具体那一位客户,可以用一个User 对象保存RemoteEndPoint
黄富国 2019-03-06
  • 打赏
  • 举报
回复
1,每个socket 都会有相对应的RemoteEndPoint , 你用dect 在socket 第一次连接时保存socket的RemoteEndPoint 作为用户的标记
2,使用心跳机制去判断用户是否在线, 每个一定时间客户端向服务器发送心跳包,再回应客户端, 双方记录心跳时间,如果大于心跳时间则判断为掉线

16,722

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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