非IOCP客户端发送/ recv错误与IOCP服务器

时间:2015-12-11 09:23:38

标签: c++ iocp

请理解我是IOCP的新手,我的代码可能不是那么完美。

我在这里尝试过很多例子,没有人能帮助我。 我的实际问题是在客户端,我不知道我是否正确连接到IOCP服务器,如果我正确发送数据并且recv给了我WSAerror 10038 ......

    WSADATA wsd;
    struct addrinfo *result = NULL, *ptr = NULL, hints;
    WSAOVERLAPPED RecvOverlapped;
    SOCKET ConnSocket = INVALID_SOCKET;
    WSABUF DataBuf;
    DWORD RecvBytes, Flags;
    CRITICAL_SECTION criti;
    char buffer[DATA_BUFSIZE];
    int err = 0;
    int rc;

    // Load Winsock
    rc = WSAStartup(MAKEWORD(2, 2), &wsd);
    if (rc != 0) {
        return 1;
    }

    // Make sure the hints struct is zeroed out
    SecureZeroMemory((PVOID)& hints, sizeof(struct addrinfo));

    // Initialize the hints to retrieve the server address for IPv4
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    rc = getaddrinfo(IP, Port, &hints, &result);
    if (rc != 0) {
        return 1;
    }

    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
        if ((ConnSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) == INVALID_SOCKET){

            freeaddrinfo(result);
            return 1;
        }

        rc = connect(ConnSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (rc == SOCKET_ERROR) {

            if (WSAECONNREFUSED == (err = WSAGetLastError())) {
                closesocket(ConnSocket);
                ConnSocket = INVALID_SOCKET;
                continue;
            }

            freeaddrinfo(result);
            closesocket(ConnSocket);
            WSACleanup();
            return 1;
        }
        break;
    }
    if (ConnSocket == INVALID_SOCKET) { 

        freeaddrinfo(result);
        return 1;
    }

    int nZero = 0;

    // Make sure the RecvOverlapped struct is zeroed out
    SecureZeroMemory((PVOID)& RecvOverlapped, sizeof(WSAOVERLAPPED));

    // Create an event handle and setup an overlapped structure.
    RecvOverlapped.hEvent = WSACreateEvent();
    if (RecvOverlapped.hEvent == NULL) {

        freeaddrinfo(result);
        closesocket(ConnSocket);
        return 1;
    }

    DataBuf.len = DATA_BUFSIZE;
    DataBuf.buf = buffer;

    // send data to server here?
    // removed the packets, it`s not supposed to be public

    // Call WSARecv until the peer closes the connection
    // or until an error occurs
    while (1) {

        Flags = 0;
        RecvBytes = 0;


        rc = WSARecv(ConnSocket, &DataBuf, 1, &RecvBytes, &Flags, &RecvOverlapped, NULL);
        if ((rc == SOCKET_ERROR) && (WSA_IO_PENDING != (err = WSAGetLastError()))) {

            closesocket(ConnSocket);
            break;

        }

        rc = WSAWaitForMultipleEvents(1, &RecvOverlapped.hEvent, TRUE, INFINITE, TRUE);
        if (rc == WSA_WAIT_FAILED) {    

            break;
        }

        rc = WSAGetOverlappedResult(ConnSocket, &RecvOverlapped, &RecvBytes, FALSE, &Flags);
        if (rc == FALSE) {

            break;
        }


        // here I have a protocol where I read the received data

        WSAResetEvent(RecvOverlapped.hEvent);

        // If 0 bytes are received, the connection was closed
        if (RecvBytes == 0)
            break;
    }

    WSACloseEvent(RecvOverlapped.hEvent);
    closesocket(ConnSocket);
    freeaddrinfo(result);

    WSACleanup();

我希望能够发送数据并从IOCP接收响应,但是如果我发送3个数据包,那么当我发回3个数据包时,我只接收2个,有时甚至1个。 有些人可以向我展示一个连接并将+ recv数据发送到IOCP服务器的工作示例吗?

非常感谢!

1 个答案:

答案 0 :(得分:0)

您正在使用TCP。 TCP是协议,而不是数据报协议。你无法告诉它要发送什么数据包,它不能告诉你收到了什么数据包(它甚至不知道,因为它是在IP层处理的)。它只是不起作用。

这句话充满了智慧:“TCP是一种双向的,面向连接的字节流协议,提供可靠的有序传送,但不保留应用程序消息边界。”将“TCP”打入您最喜爱的搜索引擎并进行学习,直到您准确理解该句子中的每个单词的含义。在你这样做之前,你永远不会写出可靠的,甚至是正确的TCP代码。

服务器是使用IOCP还是其他内部架构对客户端没有影响。这完全是看不见的。