切断時に shutdown() の第2引数にSD_BOTHを指定した場合、自身の処理には何の影響もありませんが、接続相手側でエラーが発生します。
これはいきなり一方的に切断処理を行うためであり、親切な方法ではないからです。
ということで、お行儀の良い切断処理方法について。
まず送信側を無効にし、受信バッファに残っているデータを全て読み込みます。
その後、受信側も無効にしてソケットを閉じます。
シャットダウン処理を送信側/受信側で個別に行うだけです。
DWORD CClientSock::Disconnect()
{
int sockRet = 0;
DWORD ret = SOCK_SUCCESS;
ret = shutdown(m_sock, SD_SEND);
while(TRUE)
{
CHAR buff[4096];
ret = recv(m_sock, buff, sizeof(buff), 0);
if( (ret == SOCKET_ERROR) || (ret == 0) )
{
break;
}
}
ret = shutdown(m_sock, SD_BOTH);
closesocket(m_sock);
return ret;
}