当前位置: 首页 > 知识库问答 >
问题:

使用SFML验证实时网络上发送的数据包

毕宏盛
2023-03-14

我正在构建一个可联网的程序,它用SFML UDP库在2D屏幕上传输图形变化。

我想在数据被发送到连接两侧的屏幕之前做一个验证条件。我正在考虑将单个字节作为0或1发送,以表示数据的成功接收和同步。

(见图)

    Server-------( updates )----->Client  
       |                             |  
  ( wait for )<---( 1 or 0 )-----Send Byte  
       |                             |  
    ( if 1 )                ( if byte received )  
       |                             |  
    Screen                        Screen  

在更新屏幕之前,来回ping以确保数据在两端都得到了验证,然后随后运行同一件事的另一次迭代(当然是无限期的),这似乎是合乎逻辑的。

另外,在网络上发送一个字节,而不是做其他事情,比如尝试与时间同步,是不是更慢?有没有更好的方法用FPS做这件事呢?

SFML的答案可能是最好的。

共有1个答案

何兴邦
2023-03-14

如果您坚持使用UDP,因为性能可能很重要(即使您认为性能很重要,TCP也可能会完成这项工作),您的客户端应该发送它的命令/更改/数据,并且只对接收到的数据作出反应,而永远不要费心发回布尔值(或单个比特),因为有更好的方法来处理这一点,这是对整个数据包的巨大浪费。

  1. 如果客户端从未收到请求的特定返回值,只需在给定的时间阈值后将请求重新发送到服务器,并希望得到最好的结果。
  2. 如果客户端没有变化,服务器也没有变化,只需重新绘制屏幕(或等待客户端更改)
  3. 如果在一个或多个resent请求之后服务器没有任何信息,请将问题通知客户端。(连接丢失或服务器错误)

在我所描述的内容中,服务器只需要响应一次来自客户机的请求,然后就会忘记它。

  1. 如果服务器从未接收到请求(因此从未响应客户端),则客户端无论如何都将发回其请求。
  2. 如果服务器响应在服务器和客户端之间丢失,客户端将在时间阈值之后再次将其请求发送回服务器。

很难给你一个正确的解决方案,因为我们缺乏关于你想要实现的项目的信息。

但假设这是一场游戏。

在游戏中,你不会信任客户机,所以玩家所做的每一个命令都被发送到服务器。服务器处理命令,做所有的计算,并为整个游戏跟踪所有玩家。

然后,服务器将新位置返回给客户端。客户端仅显示来自服务器的更改。例如,客户端从不移动键盘输入上的播放机。输入只需按原样发送到服务器,客户机从服务器接收一个新位置,移动指定的图形,然后呈现到屏幕上。

这样,您仍然不信任客户机,您只是在服务器响应之前猜测。

策略是协议不可知的,因为你自己处理问题。

如果您要发送大量只与发送时间相关的数据,则UDP将完成这项工作。想想视频会议或语音聊天,当你丢失了一个数据包,再发回去已经太晚了。

如果您要发送中等数量的信息,比如每秒只发送60次位置信息,那么接收的顺序可能比带宽或延迟更重要,因此TCP可能是一种可行的方法。

如果您要有一个单独的服务器应用程序,不要让它也显示在屏幕上,只需在服务器机器上运行另一个客户机,通过localhost连接。

 类似资料:
  • 虽然之前我们已经提到过不建议直接使用 LogStash::Inputs::TCP 和 LogStash::Outputs::TCP 做转发工作,不过在实际交流中,发现确实有不少朋友觉得这种简单配置足够使用,因而不愿意多加一层消息队列的。所以,还是把 Logstash 如何直接发送 TCP 数据也稍微提点一下。 配置示例 output { tcp { host => "19

  • 本文向大家介绍iOS开发使用XML解析网络数据,包括了iOS开发使用XML解析网络数据的使用技巧和注意事项,需要的朋友参考一下 前言:本篇随笔介绍的是XML解析。 正文: 1、XML解析方式有2两种: DOM:一次性将整个XML数据加载进内存进行解析,比较适合解析小文件SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件 2、IOS中XML解析方案有很多种:   2-1、第三方

  • 问的都是数据结构的问题 1.给一个整数,怎么把它翻转(123转成321) 我说用字符串他说不行 2.忘了 3.有两个整数型数组,里面的整数范围都是1-1000w,问怎么找出两个数组中相同的数字 已挂

  • 我按照本文创建了一个用于测试kerberos身份验证的java程序:https://docs.oracle.com/javase/jndi/tutorial/ldap/security/gssapi.html 我唯一更改的是配置文件。 当我将windows客户端的DNS设置指向内部windows DNS/Kerb服务器时,该程序运行良好,但当我使用单独的公共DNS服务器时,该程序会超时,即使:1.

  • 我已通过axios在阵列上发送数据(mySplitDays[splitDayIndex]=splitDay),但我有一个错误。。。 [Vue warn]:数据()中的错误:“引用错误:未定义mySplitDays” ReferenceError:未定义mySplitDays [Vue warn]:呈现错误:“TypeError:无法读取未定义的属性'length'” TypeError:无法读取P

  • 我使用Firebase实时数据库作为后端。我希望每个请求最多增加1个。例如: 这不管用。 在前端,我发送“数据1”。我应该如何创建“.validate”规则?