void CClientSocket::Disconnect()
{
// 利用setsockopt(MSDN)函数设定套接字的选项,把此套接字设定为:
// 假如有数据未发送,等待数据发送完后再关闭此套接字。
//
// If we're supposed to abort the connection, set the linger value on the socket to 0.
// https://blog.csdn.net/factor2000/article/details/3929816
// 设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态
LINGER lingerStruct;
lingerStruct.l_onoff = 1;
lingerStruct.l_linger = 0;
setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, (char *)&lingerStruct, sizeof(lingerStruct) );
CancelIo((HANDLE) m_Socket); // 异步socket优雅的关闭,关闭socket时防止未发送的数据丢失
InterlockedExchange((LPLONG)&m_bIsRunning, false); // 原子操作
closesocket(m_Socket);
SetEvent(m_hEvent); // 设置为有信号
m_Socket = INVALID_SOCKET;
}
code来自 Gh0st