Sockets 重新连接以太网时,UDP套接字写入过期的数据包。当以太网断开连接时,如何从套接字刷新写缓冲区?

Sockets 重新连接以太网时,UDP套接字写入过期的数据包。当以太网断开连接时,如何从套接字刷新写缓冲区?,sockets,udp,winsock,ethernet,Sockets,Udp,Winsock,Ethernet,我有一个“传输线程”,它管理一个套接字(#include WinSock2.h),用于传输我的应用程序所需的所有UDP数据。该应用程序是在Windows 10上运行的C++ Windows应用程序。我每秒向子网广播地址发送大约5个数据包,每个数据包少于200字节 问题是,当我断开以太网连接时,套接字的写入缓冲区中似乎有一些未发送的数据,我无法清除这些数据 当我的应用程序检测到以太网丢失时,我关闭(closesocket)并重新打开套接字。重新连接后,套接字立即发送几条旧消息,这些消息是在以太网断

我有一个“传输线程”,它管理一个套接字(#include WinSock2.h),用于传输我的应用程序所需的所有UDP数据。该应用程序是在Windows 10上运行的C++ Windows应用程序。我每秒向子网广播地址发送大约5个数据包,每个数据包少于200字节

问题是,当我断开以太网连接时,套接字的写入缓冲区中似乎有一些未发送的数据,我无法清除这些数据

当我的应用程序检测到以太网丢失时,我关闭(closesocket)并重新打开套接字。重新连接后,套接字立即发送几条旧消息,这些消息是在以太网断开连接时“发送”的

我认为这个问题超出了我的应用范围。我在应用程序运行时断开了以太网连接,然后关闭了应用程序。重新连接后,我立即看到一些消息被传输,尽管应用程序不再运行

我尝试过的事情(运气不佳):

我试过调用
shutdown(m_sock,SD_两者)紧靠
闭合插座(m_sock)之前

我尝试在关闭前立即向套接字写入一个满是零的缓冲区

我无法设置
SO_DONTLINGER
选项,因为我的套接字是
SOCK_DGRAM

当我尝试WSAIoctl(m_sock,SIO_FLUSH,NULL,0,NULL,0,&dwBytesRead,&wsol,NULL)
时,它返回错误997(WSA_IO_挂起)

我不知道如何阻止IO挂起


无论是
WSASendDisconnect(m_sock,NULL)
还是
CancelIo((HANDLE)m_sock)
都不起作用,而且都没有发出错误信号

据我所知,问题不在于我的软件或本地NIC。在通过交换机连接到局域网上的其他设备之前,我的NIC已连接到以太网集线器


集线器的存在导致了所描述的行为。没有集线器,我不会经历任何“刷新”或发送过期的数据包

据我所知,问题不在于我的软件或本地NIC。在通过交换机连接到局域网上的其他设备之前,我的NIC已连接到以太网集线器


集线器的存在导致了所描述的行为。没有集线器,我不会经历任何“刷新”或发送过期的数据包

您无法控制操作系统缓冲传出数据包的方式。一旦您将数据包放入内核的缓冲区,它就不在您的掌控之中了。仅供参考,网络被设计为具有瞬时中断的弹性,因此,当网络连接丢失时,为什么不立即丢弃传出数据包,以及为什么它们在重新连接时会重新发送。停机需要一段时间才能真正生效。你真正能做的就是检测网络断开(Windows有API回调),这样你就可以尽快停止发送数据包,但你不能清除你已经“发送”的数据包。NIC是否有一个设置可以帮助解决这个问题?我不知道你无法控制操作系统如何缓冲发送的数据包。一旦您将数据包放入内核的缓冲区,它就不在您的掌控之中了。仅供参考,网络被设计为具有瞬时中断的弹性,因此,当网络连接丢失时,为什么不立即丢弃传出数据包,以及为什么它们在重新连接时会重新发送。停机需要一段时间才能真正生效。你真正能做的就是检测网络断开(Windows有API回调),这样你就可以尽快停止发送数据包,但你不能清除你已经“发送”的数据包。NIC有没有设置可以帮助解决这个问题?我不知道