getQueedCompletionStatus接收旧数据

GetQueuedCompletionStatus recevies old data

本文关键字:数据 getQueedCompletionStatus      更新时间:2023-10-16

如果您尝试运行我的脚本,则可以看到GetQueuedCompletionStatus在第二个wsarecv调用后不会阻止。我不明白为什么此代码无法正常工作。该代码有点混乱,但很简单,因此应该可以工作。

服务器:

#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <thread>
#include <iostream>
using namespace std;
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")

WSADATA wsaData;
int iResult;
HANDLE CompletionPort;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[200];
DWORD BytesSEND;
DWORD BytesRECV;
DWORD RecvBytes;
sockaddr_in local;
DWORD Flags;
int iSendResult;

void serverWorkerThread() {
OVERLAPPED lpol2;
DWORD Flags = 0;
DWORD BytesTransferred;
DWORD is = 0;
DWORD sentBytes;
bool kage = 0;
WSABUF wsabuf;
CHAR Buffer2[200];

while (true) {
    if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, &is, (LPOVERLAPPED*)& lpol2, INFINITE) == 0)
    {
        printf("GetQueuedCompletionStatus() failed with error %dn", GetLastError());

    }
    else
        printf("GetQueuedCompletionStatus() is OK!n");
    cout << DataBuf.buf << endl;
    cout << is;
    DataBuf.len = 14;
    ZeroMemory(&(Overlapped), sizeof(OVERLAPPED));


        if (WSASend(ClientSocket, &DataBuf, 1, &sentBytes, 0,
            NULL, NULL) == SOCKET_ERROR)
        {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
                printf("WSASend() failed with error %dn", WSAGetLastError());

            }
        }
        else
            printf("WSASend() is OK!n");

    ZeroMemory(&(lpol2), sizeof(OVERLAPPED));
    wsabuf.buf = Buffer2;
    wsabuf.len = 200;
    BytesTransferred = 0;
    is = 0;

    ZeroMemory(&(Overlapped), sizeof(OVERLAPPED));
    Flags = 0;
    if (WSARecv(ClientSocket, &wsabuf, 1, &RecvBytes, &Flags, &Overlapped, NULL) == SOCKET_ERROR)
    {
        if (WSAGetLastError() != ERROR_IO_PENDING)
        {
            printf("WSARecv() failed with error %dn", WSAGetLastError());

        }
    }
    else printf("WSARecv() is OK!n");

}
}
int __cdecl main(void)
{

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
    printf("WSAStartup failed with error: %dn", iResult);
    return 1;
}
CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

//Now we populate the sockaddr_in structure
local.sin_family = AF_INET; //Address family
local.sin_addr.s_addr = INADDR_ANY; //Wild card IP address
local.sin_port = htons((u_short)20248); //port to use

// Create a SOCKET for connecting to server
ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ListenSocket == INVALID_SOCKET) {
    printf("socket failed with error: %ldn", WSAGetLastError());
    WSACleanup();
    return 1;
}
// Setup the TCP listening socket


iResult = bind(ListenSocket, (sockaddr*)& local, sizeof(local));
if (iResult == SOCKET_ERROR) {
    printf("bind failed with error: %dn", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}

iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
    printf("listen failed with error: %dn", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}
DataBuf.len = 2000;
DataBuf.buf = Buffer;
thread t1(serverWorkerThread);
t1.detach();
DWORD iss = 34543;

while (TRUE)
{
    ClientSocket = WSAAccept(ListenSocket, NULL, NULL, NULL, 0);
    if (ClientSocket == INVALID_SOCKET) {
        printf("accept failed with error: %dn", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }


    if (CreateIoCompletionPort((HANDLE)ClientSocket, CompletionPort, 43343, 0) == NULL)
    {
        printf("CreateIoCompletionPort() failed with error %dn", GetLastError());
        return 1;
    }
    else
        printf("CreateIoCompletionPort() is OK!n");



    Flags = 0;
    if (WSARecv(ClientSocket, &DataBuf, 1, &RecvBytes, &Flags, &Overlapped, NULL) == SOCKET_ERROR)
    {
        if (WSAGetLastError() != ERROR_IO_PENDING)
        {
            printf("WSARecv() failed with error %dn", WSAGetLastError());
            return 1;
        }
    }
    else printf("WSARecv() is OK!n");

}




// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
    printf("shutdown failed with error: %dn", WSAGetLastError());
    closesocket(ClientSocket);
    WSACleanup();
    return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}

客户端:

#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
using namespace std;
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char** argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
SOCKADDR_IN          ServerAddr;
// Server/receiver port to connect to
unsigned int         Port = 20248;
//struct addrinfo* result = NULL,
//  * ptr = NULL,
//  hints;
const char* sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
cout << sendbuf << endl;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
    printf("WSAStartup failed with error: %dn", iResult);
    return 1;
}


    // Create a SOCKET for connecting to server
    ConnectSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ldn", WSAGetLastError());
        WSACleanup();
        return 2;
    }

    // IPv4
    ServerAddr.sin_family = AF_INET;
    // Port no.
    ServerAddr.sin_port = htons(Port);
    // The IP address
    ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    // Connect to server.
    iResult = connect(ConnectSocket, (SOCKADDR*)& ServerAddr, sizeof(ServerAddr));
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
        printf("socket failed with error: %ldn", WSAGetLastError());
        WSACleanup();
        return 3;
    }


if (ConnectSocket == INVALID_SOCKET) {
    printf("Unable to connect to server!n");
    WSACleanup();
    return 4;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
    printf("send failed with error: %dn", WSAGetLastError());
    closesocket(ConnectSocket);
    WSACleanup();
    return 5;
}
printf("Bytes Sent: %ldn", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
    printf("shutdown failed with error: %dn", WSAGetLastError());
    closesocket(ConnectSocket);
    WSACleanup();
    return 6;
}
// Receive until the peer closes the connection
do {
    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
    if (iResult > 0)
        printf("Bytes received: %dn", iResult);
    else if (iResult == 0)
        printf("Connection closedn");
    else
        printf("recv failed with error: %dn", WSAGetLastError());
} while (iResult > 0);
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;

}

我发现了问题:客户高潮的连接,使GetQueuedCompletionstatus保持运行