-1

Please understand that I am new to IOCP and my code may not be so perfect.

I tried many examples from around here, neither one helps me. My actual problem is in the client side, I have no idea if I am connecting properly to a IOCP server, neither if I send the data properly and recv gives me 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();

I expect to be able to send data and receive the response from IOCP, but if I send 3 packets, I receive back 2 only or sometimes even 1, when I am sending 3 packets back. Can some show me a working example to connect and send+recv data to a IOCP server?

Many thanks!

Gangnus
  • 24,044
  • 16
  • 90
  • 149
C. Raluca
  • 75
  • 1
  • 2
  • 10

1 Answers1

0

You're using TCP. TCP is a stream protocol, not a datagram protocol. You cannot tell it what packets to send, and it cannot tell you what packets it received (it doesn't even know because that's handled at the IP layer). It just doesn't work that way.

This sentence is packed with wisdom: "TCP is a bidirectional, connection oriented, byte stream protocol that provides reliable, ordered delivery but does not preserve application message boundaries." Punch "TCP" into your favorite search engine and study until you understand precisely what every word in that sentence means. You will never write reliable, or even correct, TCP code until you do.

Whether the server is using IOCP or some other internal architecture has no effect on clients. That's totally invisible.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278