奇怪的closesocket()行为

时间:2015-03-09 12:04:25

标签: c++ sockets winapi network-programming winsock

我在调用closesocket()时发现了一种奇怪的行为。如果我创建一个调用recv()的线程,那么closesocket()会向另一方发送RST数据包。但是,如果我不创建接收线程,则closesocket()将执行正常断开连接(4次握手)。

以下代码将导致closesocket()发送RST数据包:

#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <process.h>

unsigned int __stdcall thread(void *s)
{
    char buffer[1024];
    recv((SOCKET)s, buffer, 1024, 0);

    return 0;
}

int main()
{
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("173.194.116.18");
    addr.sin_port = htons(80);
    connect(s, (sockaddr*)&addr, sizeof(addr));

    // Start thread
    _beginthreadex(0, 0, thread, (void*)s, 0, 0);
    Sleep(1000); // give thread some time to start

    // RST packet will be sent (if you remove the receive thread then a graceful disconnection will be performed)
    closesocket(s);

    return 0;
}

注意:我正在使用阻塞套接字。

1 个答案:

答案 0 :(得分:1)

如果是的话 客户端发送多个字节,服务器将读取第一个字节并使用其接收队列中的数据调用close,从而将RST发送到客户端。在调用recv()等待来自的响应时,客户端将被阻止 服务器。收到RST后,DieWithError()报告问题由对等方重置连接。 因此可以在调用close之前使用shutdown。 我希望本文能够帮助您了解RST http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/TCPRST.pdf