【问题标题】:Packet loss during 3way handshake3次握手过程中丢包
【发布时间】:2012-03-12 11:33:46
【问题描述】:

我需要在用 c++(使用 winsock 2)编写的客户端和服务器应用程序之间执行 3way 停止和等待握手以进行分配。客户端发送一个 SYN。服务器增加客户端序列号并发送 SYN-ACK。客户端增加服务器序列号并发送 ACK。

为了模拟丢包,客户端和服务器连接到一个中间Router程序,该程序偶尔不转发包,造成丢包。我应该如何构建我的 sendto()、select()、recvfrom() 语句来解决可能的数据包丢失问题?

例如,如果 SYN 丢失并且客户端超时,则重新发送它。如果 SYN-ACK 丢失,客户端超时并重新发送 SYN。我不知道如果 ACK 丢失了该怎么办。

编辑:在我的客户端上基本上是这样的:

  • 发送 SYN。
  • select() 语句失败时循环并重新发送 SYN
  • 接收 SYN-ACK
  • 发送确认
  • 如果 ACK 丢失,循环以可能重新接收 SYN-ACK。

我如何知道何时停止循环?

【问题讨论】:

  • 看起来像以前问过的问题:stackoverflow.com/questions/1460640/…
  • 我知道 SYN-ACK 将被重新发送,然后 ACK 将被重新发送,但是如何使用 select() 检查它?我必须循环 recvfrom() 并检查它是否是相同的 SYN-ACK?
  • 在 TCP 中,您无法控制 SYN 和 ACK。您唯一能做的就是将套接字置于非阻塞模式,以便connect() 异步工作,然后使用select() 的超时功能等待连接建立。如果select() 超时,请关闭套接字并重新开始。
  • 这是我自己通过UDP实现的TCP。套接字的类型是 SOCK_DGRAM。
  • 最后的ACK没有回复。一旦客户端发送该 ACK,它就必须考虑在其端建立的连接。服务器是否收到 ACK 对客户端来说并不重要。如果服务器从未收到 ACK,则不会在其端建立连接。最终,客户端的套接字活动将失败并出现错误。

标签: c++ sockets tcp winsock handshake


【解决方案1】:

select 可用于检查何时可以无阻塞地读取套接字。

至于查看ACK属于哪个发送的数据包,你查看序列号。

如果您在超时时间内没有收到 ACK,您只需重新发送最后一个数据包。不管你发送什么样的数据包,如果你没有收到 ACK 你应该重新发送它。

【讨论】:

    猜你喜欢
    • 2014-12-16
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2016-05-24
    • 1970-01-01
    • 2020-04-09
    相关资源
    最近更新 更多