Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在windows中从同一套接字同时读写 我在Windows上用C++编写服务器。在连接时,服务器创建两个线程来处理请求——一个线程不断地从套接字读取输入,另一个线程不断地向套接字写入输出。我在使用它时遇到了问题,因为当没有来自客户端的输入但要发送到它的输出时,线程1在recv上阻塞,使得线程2在发送时阻塞,而不写入它的数据_C++_Windows_Sockets_Send_Recv - Fatal编程技术网

在windows中从同一套接字同时读写 我在Windows上用C++编写服务器。在连接时,服务器创建两个线程来处理请求——一个线程不断地从套接字读取输入,另一个线程不断地向套接字写入输出。我在使用它时遇到了问题,因为当没有来自客户端的输入但要发送到它的输出时,线程1在recv上阻塞,使得线程2在发送时阻塞,而不写入它的数据

在windows中从同一套接字同时读写 我在Windows上用C++编写服务器。在连接时,服务器创建两个线程来处理请求——一个线程不断地从套接字读取输入,另一个线程不断地向套接字写入输出。我在使用它时遇到了问题,因为当没有来自客户端的输入但要发送到它的输出时,线程1在recv上阻塞,使得线程2在发送时阻塞,而不写入它的数据,c++,windows,sockets,send,recv,C++,Windows,Sockets,Send,Recv,有没有一种方法可以发送到一个套接字,尽管它已经在阻塞recv中 谢谢 编辑: 我拿出相关代码,复制了这个问题。如果我注释掉对readThread的afxthread调用,则数据将被发送。否则就不是了。客户端是一个简单的客户端,它打印接收到的内容 SOCKET m_sockIOSrv = NULL; SOCKET m_sockIO = NULL; UINT readThread(LPVOID args) { WSABUF DataBuf; DWORD RecvBytes;

有没有一种方法可以发送到一个套接字,尽管它已经在阻塞recv中

谢谢

编辑:

我拿出相关代码,复制了这个问题。如果我注释掉对readThread的afxthread调用,则数据将被发送。否则就不是了。客户端是一个简单的客户端,它打印接收到的内容

SOCKET m_sockIOSrv = NULL;
SOCKET m_sockIO = NULL;

UINT readThread(LPVOID args)
{
    WSABUF DataBuf;
    DWORD RecvBytes;
    DWORD Flags = 0 ;
    char buf[4096];
    DataBuf.len = 4096;
    DataBuf.buf = buf;
    while (true)
    {
        int ret = WSARecv(m_sockIO, &DataBuf, 1, &RecvBytes, &Flags, NULL,     NULL); // Read some data...
        if (ret == SOCKET_ERROR)
        {
            printf("ERROR: WSARecv: %d", WSAGetLastError());
            return 1;
        }
        printf("jobleader - got %d from recv\n", RecvBytes);
    }
    return 0;
}

UINT writeThread(LPVOID args)
{
    WSABUF DataBuf;
    DWORD SendBytes;
    DWORD Flags;

    char buf[] = { 'a', 'a', 'a' };
    DataBuf.len = 3;
    DataBuf.buf = buf;
    while (true)
    {
        DWORD dwWritten;
        WSASend(m_sockIO, &DataBuf, 1, &dwWritten, 0, NULL, NULL);
    }
    return 0;
}

SOCKET ServerSocket(unsigned int & port) {
    // Our server socket
    SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
    if (s == INVALID_SOCKET)
        return s;

    SOCKADDR sa;
    sa.sa_family = AF_INET;
    memset(sa.sa_data, 0, sizeof(sa.sa_data));
    if (bind(s, &sa, sizeof(sa))) {
        closesocket(s);
        return INVALID_SOCKET;
    }

    struct sockaddr_in sa_in;
    int sz = sizeof(sa_in);
    if (getsockname(s, (struct sockaddr *)&sa_in, &sz)) {
        closesocket(s);
        return INVALID_SOCKET;
    }

    if (listen(s, 50)) {
        closesocket(s);
        return INVALID_SOCKET;
    }

    port = ntohs(sa_in.sin_port);
    return s;
}
int _tmain(int argc, _TCHAR* argv[])
{
    unsigned int ioPort = 0;
    WORD wVersionRequested = MAKEWORD(2, 2);
    WSADATA wsaData;
    if (WSAStartup(wVersionRequested, &wsaData))
    {
        if (!AfxSocketInit())
        {
            printf("ERROR: Unable to initialize WinSock DLL");
            exit(2);
        }
    }
    m_sockIOSrv = ServerSocket(ioPort);
    if (m_sockIOSrv == INVALID_SOCKET) {
        int lastError = GetLastError();
        printf("ERROR: StartIOSockets Failed to start socket     %d.\n",lastError);
        return 1;
    }
    printf("Listening on %d\n", ioPort);
    m_sockIO = accept(m_sockIOSrv, NULL, NULL);
    AfxBeginThread(&readThread, (LPVOID)NULL);
    AfxBeginThread(&writeThread, (LPVOID)NULL);
    getchar();
}

你不能在recv上使用MSG_DONTWAIT标志,这样它就不会阻塞吗?@dietbacon否,因为它会让我忙着在套接字和cosume cpu上无需任何费用地一直等待。你发送数据而不请求吗?是的,这段代码的主要用途是作为远程用户和子进程之间的代理。用户在套接字上发送进程的STDIN并接收STDOUT。我不知道用户何时会发送输入,所以我只能从套接字constatly读取。我只在子进程产生输出时才向它写入数据,但由于recv阻塞,它会被卡住。我可以使用两个不同的套接字,但是客户端代码已经存在,linux代码工作正常,这是唯一一个出现问题的windows。我不想在windows上处理太多现有代码。windows中的正确解决方案是使用异步I/O,但这可能会使与Linux实现共享代码变得困难。也许选择会奏效?