我在工作者线程中用WSASend,GetQueuedCompletionStatus可以接到发送的结果,在其他的线程中用WSASend,为什么GetQueuedCompletionStatus就得不到结果呢?

解决方案 »

  1.   

    代码如下:
    我刚学习完成端口,还请大家多帮帮忙啊#pragma comment(lib, "ws2_32")
    #include "Winsock2.h"
    #include "windows.h"
    #include <iostream>using namespace std;typedef struct
    {
    SOCKET m_socket;
    SOCKADDR_IN m_addr;
    }PRO_HEAD_DATA,*PPRO_HEAD_DATA;typedef struct
    {
    OVERLAPPED Overlapped;
    WSABUF DataBuf;
    CHAR Buffer[4096];
    } PER_IO_OPERATION_DATA, *PPER_IO_OPERATION_DATA;DWORD WINAPI PerFunc(LPVOID lpParameter)
    {
    SOCKET Accept=(SOCKET)lpParameter;
    WSABUF DataBuf;
    LPWSAOVERLAPPED Overlapped=NULL;
    DWORD Flags = 0;
    DWORD dwRecv = 0;
    DataBuf.buf="sss";
    DataBuf.len=strlen("sss");
    while(TRUE)
    {
    Sleep(1000);
    if(WSASend(Accept,&DataBuf,1,&dwRecv,Flags,Overlapped,NULL)==SOCKET_ERROR)
    {
    cout<<"other thread send error"<<endl;
    }
    }
    return TRUE;
    }
    DWORD WINAPI ThreadProc(LPVOID lpParameter)
    {
    HANDLE CompletionPort=(HANDLE)lpParameter;
    DWORD BytesTransferred;
    PPRO_HEAD_DATA PerHeadData;
    PPER_IO_OPERATION_DATA PerIoData;
    while(TRUE)
    {
    if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHeadData, (LPOVERLAPPED*)&PerIoData, INFINITE))
    {
    if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
    {
    cout << "closing socket" << PerHeadData->m_socket << endl; closesocket(PerHeadData->m_socket); delete PerIoData;
    delete PerHeadData;
    continue;
    }
    else
    {
    cout<<"GetQueuedCompletionStatus failed!"<<endl;
    }
    return 0;
    }
    if(BytesTransferred==0)
    {
    cout << "closing socket" << PerHeadData->m_socket << endl;
    closesocket(PerHeadData->m_socket);
    delete PerIoData;
    delete PerHeadData;
    continue;
    }
    cout << PerHeadData->m_socket <<" IP:"<<inet_ntoa(PerHeadData->m_addr.sin_addr)<<":"<<PerHeadData->m_addr.sin_port<<" 发送过来的消息:"<< PerIoData->Buffer << endl; DWORD Flags = 0;
    DWORD dwRecv = 0;
    ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
    PerIoData->DataBuf.buf = PerIoData->Buffer;
    PerIoData->DataBuf.len = 4096;
    WSARecv(PerHeadData->m_socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
    } return TRUE;
    }int main()
    {
    SOCKET Listen;
    SOCKET Accept;
    HANDLE CompletionPort;
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
     
    wVersionRequested = MAKEWORD( 2, 2 );
     
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) {
    return 1;
    } if ( LOBYTE( wsaData.wVersion ) != 2 ||
    HIBYTE( wsaData.wVersion ) != 2 ) {
    WSACleanup( );
    return 1; 
    } CompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); for(int i=0;i<6;i++)
    {
    HANDLE hThread=CreateThread(NULL,0,ThreadProc,CompletionPort,0,NULL);
    CloseHandle(hThread);
    } SOCKADDR_IN srvaddr;
    srvaddr.sin_family=AF_INET;
    srvaddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
    srvaddr.sin_port=htons(6880); Listen=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED); bind(Listen,(SOCKADDR*)&srvaddr,sizeof(SOCKADDR)); listen(Listen,5); while(TRUE)
    {
    SOCKADDR_IN clientaddr;
    int len=sizeof(SOCKADDR_IN);
    Accept=WSAAccept(Listen,(SOCKADDR*)&clientaddr,&len,NULL,0);
    cout<<Accept<<":进入服务器"<<endl; HANDLE Thread=CreateThread(NULL,0,PerFunc,(LPVOID)Accept,0,NULL);
    CloseHandle(Thread); PRO_HEAD_DATA *PreHeadData=new PRO_HEAD_DATA;
    PreHeadData->m_socket=Accept;
    PreHeadData->m_addr=clientaddr; CreateIoCompletionPort((HANDLE)Accept,CompletionPort,(DWORD)PreHeadData,0); PER_IO_OPERATION_DATA *PerIoData=new PER_IO_OPERATION_DATA; ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA)); PerIoData->DataBuf.buf=PerIoData->Buffer;
    PerIoData->DataBuf.len=4096; DWORD Flags = 0;
    DWORD dwRecv = 0;
    WSARecv(Accept, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
    } return 0;
    }