c - 退出阻塞的 recv() 调用

标签 c sockets winsock

<分区>

我想退出阻塞的 recv() 调用。基于此question ,我应该执行以下操作:

shutdown(s, SD_RECEIVE);

但它不起作用,recv() 仍然阻塞!


编辑:

这是我使用的代码:

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

unsigned int __stdcall recvThread(void *p)
{
    SOCKET s = *((SOCKET*)p);

    char buffer[2048];
    int size;

    do
    {
        size = recv(s, buffer, 2048, 0);

        if (size > 0)                               
        {
            printf("Some data received\n");
        }
        else if (size == 0)
        {
            printf("Disconnected\n");
        }
        else
        {
            printf("Disconnected, error occured\n");
        }

    } while (size > 0);

    return 0;
}

int main()
{
    // Initialize Winsock
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);

    // Create socket
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);

    // Connect
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("192.168.1.4");
    addr.sin_port = htons(atoi("12345"));
    if (connect(s, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
    {
        printf("Unable to connect\n");
    }
    else
    {
        printf("Connected\n");
    }

    // Start recv() thread
    HANDLE hRecvThread = (HANDLE)_beginthreadex(0, 0, recvThread, &s, 0, 0);

    Sleep(3000);

    // Exit blocking recv()
    shutdown(s, SD_RECEIVE);

    getchar();
    return 0;
}

最佳答案

您需要按照您链接到的问题中提到的那样关闭输入。 请参阅 msdn 和此处有关 shutdown() 的文档:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspx

文档中的相关引用:

The shutdown function is used on all types of sockets to disable reception, transmission, or both.
If the how parameter is SD_RECEIVE, subsequent calls to the recv function on the socket will be disallowed. This has no effect on the lower protocol layers. For TCP sockets, if there is still data queued on the socket waiting to be received, or data arrives subsequently, the connection is reset, since the data cannot be delivered to the user. For UDP sockets, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.
If the how parameter is SD_SEND, subsequent calls to the send function are disallowed. For TCP sockets, a FIN will be sent after all data is sent and acknowledged by the receiver.
Setting how to SD_BOTH disables both sends and receives as described above.

key 是发送的 FIN。这将由服务器处理并关闭套接字,导致您的 recv() 调用返回。

关于c - 退出阻塞的 recv() 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29737707/

相关文章:

c - c中客户端-服务器通信失败

c - 在 C 中运行并发线程?

c - fatal error : opening dependency file

C语言 : write to file without buffering

Java、端口、套接字、通过程序管道连接

c - 发送/接收是否以相同的 block 传输数据?

c++ - 路径如何存储在这种结构中,以及如何将其转换为其他结构?

用于网络设备的 Python Syslog 服务器

sockets - Majordomo 代理吞吐量测量

c++ - C++获取HTML源