从Windows中的同一个套接字同时读写

时间:2015-08-27 13:34:57

标签: c++ windows sockets send recv

我在Windows上用C ++编写服务器。在连接时,服务器创建两个线程来处理请求 - 一个不断地从套接字读取输入,第二个不断地将输出写入它。我遇到了问题,因为当没有来自客户端的输入但输出发送给它时,线程#1阻塞了recv(),在send()上创建了两个块,而没有写入它的数据。

有没有办法发送()到套接字虽然它已经在阻塞recv()?

由于

编辑:

我拿出相关代码并转载了这个问题。如果我将AfxThreadCall注释掉readThread,则会发送数据。否则不是。客户端是一个简单的客户端,可以打印收到的内容。

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();
}

0 个答案:

没有答案