2015-12-11 2 views
-1

Veuillez comprendre que je suis nouveau à l'IOCP et que mon code n'est peut-être pas aussi parfait.Erreur d'envoi/de refus de client non-IOCP avec le serveur IOCP

J'ai essayé beaucoup d'exemples d'ici, aucun ne m'aide. Mon problème réel est dans le côté client, je ne sais pas si je me connecte correctement à un serveur IOCP, ni si j'envoie les données correctement et recv me donne 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(); 

Je compte être en mesure d'envoyer des données et de recevoir la réponse de l'IOCP, mais si j'envoie 3 paquets, je reçois seulement 2 ou parfois même 1, quand j'envoie 3 paquets en arrière. Certains peuvent-ils me montrer un exemple de travail pour se connecter et envoyer des données + recv à un serveur IOCP?

Merci beaucoup!

Répondre

0

Vous utilisez TCP. TCP est un protocole flux, pas un protocole de datagramme. Vous ne pouvez pas lui dire quels paquets à envoyer, et ne peut pas vous dire quels paquets il a reçus (il ne sait même pas parce que c'est manipulé à la couche IP). Ça ne marche pas comme ça. Cette phrase est remplie de sagesse: «TCP est un protocole bidirectionnel, orienté connexion, flux de données qui fournit une livraison fiable et ordonnée, mais ne préserve pas les limites des messages d'application. Punch "TCP" dans votre moteur de recherche préféré et étudier jusqu'à ce que vous compreniez exactement ce que signifie chaque mot de cette phrase. Vous n'écrirez jamais de code TCP fiable, voire correct, jusqu'à ce que vous le fassiez. Le fait que le serveur utilise IOCP ou une autre architecture interne n'a aucun effet sur les clients. C'est totalement invisible.

+0

merci pour l'info –