服务器和多客户端C/S模式,客户端需要定时给服务器发送心跳包,接收到服务器的报文还要给服务器返回应答报文,程序中到底在哪里给服务器返回报文呢?

ba_wang_mao 2019-11-01 05:28:53
服务器和多客户端C/S模式

(一)、客户端需要定时给服务器发送心跳包
(二)、客户端的接收线程中,接收到服务器的报文,需要给服务器返回应答报文

请问:(1)、是不是在定时器中给服务器发送心跳包,在接收线程中给服务器返回应答报文。
使用这种发送方式,会不会出现异常呢?

(2)、还是专门启动一个发送线程:
发送线程中:当检测到定时器溢出时,就发送心跳包;
当接收线程中接收服务器的报文,就发送应答报文。


我是C#小白,最好有源代码指示,谢谢!

...全文
641 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
advance_coder 2019-11-08
  • 打赏
  • 举报
回复
看来不懂网络异步模式,心跳机制一般在客户端有一段时间没给服务器发包的情况下(注:此段时间服务器也没给客户端数据),怕服务器误以为客户端掉线而主动断开与客户端之间的链接。 不知道你的底层网络模型如何设计,可以考虑单独一个线程去维护心跳。 最笨的办法不管客户端与服务器之间有无数据交互,每两分钟后客户端送一个心跳包给服务器(服务器超时需要设置2分钟+30秒,否则没等服务器收到心跳包就已经断开链接了)。 这个频率下心跳包发送不频繁,不会造成网络堵塞。
paradox_1_0 2019-11-07
  • 打赏
  • 举报
回复
不需要使用单独线程,首先第一点:你的程序使用的是阻塞模式还是非阻塞模式套接字,如果是阻塞模式,那么不需要心跳,阻塞套接字的通用做法是设置超时;如果是非阻塞套接字,这种情况通常是结合io复用的,并且具体的逻辑处理是通过状态机模式进行处理的,每个连接都对应一个连接对象实例,在每个连接实例中应该维护一个定时器对象实例,当每次接受到不管是客户端发来的心跳包也好还是正常的数据包,都需要重置定时器的当前值,给一个公式:当前时间—上次更新时间如果大于设置的阈值的时候就关闭两个对象,这里还有一个问题是如果没有数据包到来的时候这里好像也没有机会做判断啊?是不是?linux下的做法是alarm调用定时发送信号来激活对应的信号处理函数,在信号处理函数中向指定连接对象发送处理事件,,,,,啦啦啦,说的好乱
小大飞 2019-11-07
  • 打赏
  • 举报
回复
感觉搞这个领域的人就是很少,没什么开发经验。
我也想知道怎么搞,支持楼主!
ba_wang_mao 2019-11-07
  • 打赏
  • 举报
回复
因为在单片机平台下编写通信程序,会使用【中断】方式发送字节,即:发送前开启【发送完成中断】,接着会自动跳转到中断服务程序中发送缓冲区中的全部字节。

因此单片机平台下编写通信程序,如果在2个地方分别调用发送子程序,会产生冲突,因为第一个程序中的数据还没有发送完成,你如果另外一个地方调用第2个发送程序,就会引用冲突,因此转移到PC平台编程,我也会把单片机环境下的惯性思维套到PC平台下,因此会产生上述疑问。

PC平台下编写通信程序,根本就没有【中断】的概念,因为WINDOWS操作系统就不允许用户程序直接操作【硬件端口】。
ba_wang_mao 2019-11-06
  • 打赏
  • 举报
回复
引用 10 楼 wanghui0380 的回复:
串口内部有缓冲区,其实tcp内部一样有缓冲区。

缓冲区保证你可以并行写入缓冲,但是他对外发送其实是一次只发一个指令

并行写入A,B如缓冲区

B写入完成,A还没有写入完成,B入发送队列

内部发送从队列取到B,得到字节链表,然后发送,B没有发送完毕前,他不会继续下一个,也就是即使A已经写入完成,也得给我等着,所以他才不会乱


谢谢,明白啦。

第一次学习PC平台的编程,会将单片机编程的很多经验带到PC平台上,因此会产生困惑。
在PC平台编程,实际上将发送数据送到系统内部缓冲区,系统内部缓冲区由队列构成,经你这么提醒我就明白啦。

即:C#客户端可以在任意地方发送报文给服务器,反正传输到系统内部缓冲区,系统会自动帮助你管理你需要发送的报文,不要你操心。

wanghui0380 2019-11-06
  • 打赏
  • 举报
回复
串口内部有缓冲区,其实tcp内部一样有缓冲区。 缓冲区保证你可以并行写入缓冲,但是他对外发送其实是一次只发一个指令 并行写入A,B如缓冲区 B写入完成,A还没有写入完成,B入发送队列 内部发送从队列取到B,得到字节链表,然后发送,B没有发送完毕前,他不会继续下一个,也就是即使A已经写入完成,也得给我等着,所以他才不会乱
wanghui0380 2019-11-06
  • 打赏
  • 举报
回复
就像你熟悉plc一样,一个串口。你操作串口的时候操心过,我同时有2个指令发送么 你不会操心这个,串口有缓冲区,他内部自己排程。不会因为你同时2个指令就乱发。 但是有件事情需要操心,就像我说的比如你有两条指令,一条是心跳,一条是发送上传一个500M的文件 假设现在串口在上传一个500M的文件,他还能同时上传心跳么?明显不能,因为串口内部排程需要先发500M,任何才轮到心跳 所以,我们说“如果和你对接的兄弟,是死脑筋,非要认为心跳才是存活标准,那么你发那500M文件,他觉着你死了”,如果是碰到这种死脑筋的,你就只能根据协议把这500M拆成N个每次只占几百毫秒的小包,才能保证那个所谓的心跳能正常插到发送队列里
ba_wang_mao 2019-11-06
  • 打赏
  • 举报
回复
引用 7 楼 杀马特丶蛮牛 的回复:
客户端定时发心跳就行了,客户端接不接服务器返回的内容都无所谓,服务端来判断你多久没发心跳了,认为你离线



客户端到底在哪里给服务器发送呀!
因为:
(一)、客户端需要定时给服务器发送心跳包报文
(二)、客户端的接收线程中,接收到服务器的报文,需要给服务器返回应答报文
我感到困惑的是:
如果在定时器中发送心跳包报文,那么如果在客户端的接收线程中,接收到服务器的报文,给服务器返回应答报文。
这样会出现在程序中有二个地方给服务器发送报文,程序会不会产生冲突,显然这种发送不是一种好的发送方式,不知道有没有更好的发送方式呢。
杀马特丶蛮牛 2019-11-05
  • 打赏
  • 举报
回复
客户端定时发心跳就行了,客户端接不接服务器返回的内容都无所谓,服务端来判断你多久没发心跳了,认为你离线
ba_wang_mao 2019-11-05
  • 打赏
  • 举报
回复
我需要实现
1、服务器和客户端的双向通信。
2、客户端和客户端的双向通信。

所以,客户端必须向服务器发送心跳包,服务器就会知道哪个客户端在线,客户端之间也会知道哪些客户端在线。
当客户端正常退出时,服务器会广播通知所有的客户端
当服务器长时间没有收到某个客户端的心跳包时, 服务器也会广播通知所有的客户端

因此 ,我想问如下问题:

(一)、客户端需要定时给服务器发送心跳包
(二)、客户端的接收线程中,接收到服务器的报文,需要给服务器返回应答报文

请问:(1)、是不是在定时器中给服务器发送心跳包,在接收线程中给服务器返回应答报文。
使用这种发送方式,会不会出现异常呢?

(2)、还是专门启动一个发送线程:
发送线程中:当检测到定时器溢出时,就发送心跳包;
当接收线程中接收服务器的报文,置个标识,在发送线程中检测到该标识,就发送应答报文。

(3)、还是有其它好的方法呢?

我是C#小白,之前一直搞单片机开发,没有搞过PC平台开发,现在自学C#,因此最好有源代码指示,谢谢!

  • 打赏
  • 举报
回复
我之前因为工作需要也学习了socket,编写简单的聊天室。对于你的问题,1是没有啥影响的,至于2,可以这样做,不过我觉得没有必要再回复给服务端,回复给服务端干嘛?
wanghui0380 2019-11-04
  • 打赏
  • 举报
回复
恩,plc领域这个本来就这么搞啊 plc的天生就是定时器一遍一遍轮询,天生就是用一个大的消息循环判定。 我们这边也是一样,只是因为这边是多任务系统所以比plc的多了并行处置。 所以换成并行处置的模式我们来说一下 1.对于心跳,我们认为对方一般采用类似cache的相对缓存过期策略,如果对方脑袋清楚他应该使用只要有数据进入就表示存活的,这种无需特别处置。可以采用一个信号量,心跳抢的到信号量就发,抢不到就不发。 如果对方脑袋不清楚的,一定需要认为必须收到心跳指令才表示活着的,那需要拆包处置,毕竟假设一个任务字节多他要发1分钟,而你要求每半分钟必须给心跳指令,那我只能拆包,把每个任务都拆成绝对不超过20秒,才能有空闲给你发心跳。当然这种处置,你要拆,他要组装--------------------这其实就是并行任务,然后并行?tcp就一个,串口就一个,只能跟你们plc的学,把任务拆成原子级,用时间片轮流做 2.这个依旧是并行问题。在我们这边发送,接收,接收解析,解析后应答回复其实是并行的。我并不愿意如很多人那样一定非要把事情扯到线程上,只要你并行处置就好了,不必强说线程,比如你可以说消息。对你plc应该也能明白消息。因为你plc的更应该熟悉一个词“消息总线”,对,我们这里有eventbus。你把接收的数据发到消息总线,有个东西可以从消息总线解析消息--------同时他负责把解析的消息发回消息总线-------另一个东西负责从消息总线接收处理这种解析过的指令,并根据指令并行/并发去执行对应逻辑,然后给上面响应
ba_wang_mao 2019-11-04
  • 打赏
  • 举报
回复
引用 1 楼 wanghui0380 的回复:
15年的小白,这号被csdn卖出去了?
1)问题不大,不过建议使用带优先级队列发。毕竟心跳这玩意可有可无 ,如果实时要求,功能代码应该先发。心跳可以延后
2)至于应答这个就难回复了,你说你是小白,我们也不能说啥消息bus,响应式编程
只能说最最原始的
swith了

swith 功能码
case 1
功能1回复
case 2
功能2回复



我一直奋战在单片机和嵌入式领域,很少接触PC平台的编程。在单片机和嵌入式领域主要用C语言、UCDOSII、FREERTOS。C#、JAVA等语言用不上。
秋的红果实 2019-11-01
  • 打赏
  • 举报
回复
没怎么看懂,所谓心跳,主要是服务端判断客户端还活着不了,便于管理channel 在需要探测对方是否活着的时候,才发送,不要timer轮询 不用线程
wanghui0380 2019-11-01
  • 打赏
  • 举报
回复
15年的小白,这号被csdn卖出去了? 1)问题不大,不过建议使用带优先级队列发。毕竟心跳这玩意可有可无 ,如果实时要求,功能代码应该先发。心跳可以延后 2)至于应答这个就难回复了,你说你是小白,我们也不能说啥消息bus,响应式编程 只能说最最原始的 swith了 swith 功能码 case 1 功能1回复 case 2 功能2回复
1. 介绍 CAN 只定义物理层和数据链路层, 没有规定应用层,本身并不完整,需要一个高层协议来定义CAN 报文的 11/29 位标识符、8 字节数据的使用。而且,基于 CAN 总线的工业自动化应用, 越来越需要一个开放的、标准化的高层协议:这个协议支持各种 CAN 厂商设备的互用性、互换性,能够实现在CAN网络提供标准的、统一的系统通讯模式, 提供设备功能描述方式,执行网络管理功能。 2. 对象字典(OD) 对象字典是一个有序的对象组,每一个对象组采用一个16位的索引和一个8位的子索引来 寻址。 the Object Dictionary serves as aninterface between the communicationand the application. 对象字典索引的分类 3. NMT状态机 " " " " " "过程数据对象(PDO"否 "是 "否 " ") " " " " "服务数据对象(SDO"是 "是 "否 " ") " " " " "同步报文(SYNC) "是 "是 "否 " "紧急报文(EMCY) "是 "是 "否 " "网络管理(NMT) "是 "是 "是 " 1. 2. 3. 1. 心跳报文(Heartbeat) 一个节点可以被配置为心跳报文的生产者,Heartbeat的消费者一般是主站 2. NMT Boot-up NMT-Slave发布Boot up 报文通知NMT 主节点它已经从initialising状态进入pre- operational状态 3. 节点保护/寿命保护 NMT主节点发送远程帧 NMT从节点响应远程帧 数据部分包括一个触发位(bit7),触发位必须在每次节点保护应答替置"0"或者"1"。 触发位在第一次节点保护请求时置为"0"。位 0 到位 6(bits0~6)表示节点状态,可为下表的数值。 带*号的只有在支持Bootup的节点才提供,状态0不在节点保护应答出现,因为节点在 此状态下不应答节点保护报文。 4. 周期性过程数据(PDO) 传输方式 1. 事件驱动 当输入值发生变化时,数据立即被发送出去 2. 远程请求 PDO由远程帧触发,大部分设备不支持远程帧,且CIA组织不推荐使用。 3. 同步传输 RPDO:先接收到数据,但不更新到设备,只有接收到同步帧出发后,才更新,通过这种方 式实现同步。 TPDO:可以设置接收到多少个同步帧后才发送TPDO。 5. 非周期性服务数据(SDO) 建立在客户端服务器这样一种模型之上。 操作可分为下载和上传。 1. 2. 3. 4. 5. 1. 加速传输 2. 分段传输 主要用于传输超过32位的数据。 3. 块传输 与分段传输的主要区别是其将数据划分成几个单一的包,在连续的请求或者应答逐块 的的传输这些包。可以在最后一段发送CRC校验和。 6. 同步数据(SYNC) 7. 紧急报文(EMCY) COB-ID:0x080+Node_ID 1003h存放了错误的记录。 8. 设备描述文件(EDS) 以电子表格的形式呈现 ----------------------- CANopen培训资料[精选]全文共13页,当前为第1页。 CANopen培训资料[精选]全文共13页,当前为第2页。 CANopen培训资料[精选]全文共13页,当前为第3页。 CANopen培训资料[精选]全文共13页,当前为第4页。 CANopen培训资料[精选]全文共13页,当前为第5页。 CANopen培训资料[精选]全文共13页,当前为第6页。 CANopen培训资料[精选]全文共13页,当前为第7页。 CANopen培训资料[精选]全文共13页,当前为第8页。 CANopen培训资料[精选]全文共13页,当前为第9页。 CANopen培训资料[精选]全文共13页,当前为第10页。 CANopen培训资料[精选]全文共13页,当前为第11页。 CANopen培训资料[精选]全文共13页,当前为第12页。 CANopen培训资料[精选]全文共13页,当前为第13页。

110,536

社区成员

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

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

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