读书人

IOCP示例有关问题

发布时间: 2012-04-08 14:38:30 作者: rapoo

IOCP示例问题

C/C++ code
// iocpServ.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"/***   iocpSerc.c*/#include <stdio.h>#include <windows.h>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib")#define TCP_PORT 5150#define DATA_BUFSIZE 8192typedef struct{    OVERLAPPED   Overlapped;    WSABUF   DataBuffer;    CHAR     Buffer[DATA_BUFSIZE];    DWORD    BytesRecv;    DWORD    BytesSend;}PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA; typedef struct {    SOCKET  Socket; }PER_HANDLE_DATA, * LPPER_HANDLE_DATA;  DWORD WINAPI ServerWorkerThread(LPVOID);  void main(void) {    WSADATA       wsaData;    SOCKADDR_IN   InternetAddr;    SOCKET        ListenSocket;    SOCKET        AcceptSocket;    LPPER_HANDLE_DATA        perHandleData;    LPPER_IO_OPERATION_DATA    perIoData;    HANDLE        CompletionPort; //   HANDLE        hThread;    DWORD         RecvBytes;    DWORD         ThreadId;    SYSTEM_INFO   SystemInfo;    DWORD         Ret;    DWORD         Flags;    int           i;        //  加载winsock2.2    Ret = WSAStartup(0x0202, &wsaData);    //   Ret = WSAStartup(MAKEWORD(2,2), &wsaData)    if(0 != Ret)    {        printf("WSAStartup failed with error%d\n", Ret);        return;    }        //  创建一个完成端口    CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);    if(NULL == CompletionPort)    {        printf("CreateIoCompletionPort() failed with error%d\n", GetLastError());        return;    }    //  查看系统处理器个数    GetSystemInfo(&SystemInfo);        //  根据系统现有的处理器创建合理的线程数    for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)    {        HANDLE        hThread;        //  创建一个线程,把完成端口传递给它        hThread = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort, 0, &ThreadId);        if(NULL == hThread)        {            printf("CreateThread() failed with error%d\n", GetLastError());            return;        }        //  关闭线程        CloseHandle(hThread);    }        //  创建一个套接字    ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);    if(INVALID_SOCKET == ListenSocket)    {        printf("WSASocket() failed with error%d\n", WSAGetLastError());        return;    }        InternetAddr.sin_family = AF_INET;    InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);    InternetAddr.sin_port = htons(TCP_PORT);        //绑定套接字    if(SOCKET_ERROR == bind(ListenSocket, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)))    {        printf("bind() faile with error%d\n", WSAGetLastError());        return;    }        //监听套接字    if(SOCKET_ERROR == listen(ListenSocket, 5))    {        printf("listen() failed with error%d\n", WSAGetLastError());        return;    }        // 接受socket,并把它与完成端口关联    while(TRUE)    {        AcceptSocket = WSAAccept(ListenSocket, NULL, NULL, NULL, 0);        if(SOCKET_ERROR == AcceptSocket)        {            printf("WSAAccept() failed with error%d\n", WSAGetLastError());            return;        }        perHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR, sizeof(LPPER_HANDLE_DATA));        if(NULL == perHandleData)        {            printf("GlobalAlloc() failed with error %d\n", GetLastError());            return;        }        printf("Socket number %d connect\n", AcceptSocket);        perHandleData->Socket = AcceptSocket;                if(NULL == CreateIoCompletionPort((HANDLE)AcceptSocket, CompletionPort, (DWORD)perHandleData, 0))        {            printf("CreateIoCompletionPort() failed with error %d\n", GetLastError());            return;        }                perIoData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(LPPER_IO_OPERATION_DATA));        if(NULL == perIoData)        {            printf("GlobalAlloc() failed with error %d\n", GetLastError());            return;        }                ZeroMemory(&(perIoData->Overlapped), sizeof(OVERLAPPED));        [color=#FF0000]perIoData->BytesRecv = 0;[/color]        perIoData->BytesSend = 0;        perIoData->DataBuffer.len = DATA_BUFSIZE;        perIoData->DataBuffer.buf = perIoData->Buffer;                        Flags = 0;        if(SOCKET_ERROR == WSARecv(AcceptSocket, &(perIoData->DataBuffer), 1, &(RecvBytes), &Flags, &(perIoData->Overlapped), NULL))        {            if(WSAGetLastError() != ERROR_IO_PENDING)            {                printf("WSARecv() failed with error %d\n", WSAGetLastError());                return;            }        }    } } DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID){    HANDLE CompletionPort = (HANDLE)CompletionPortID;        DWORD   BytesTransferred;    LPOVERLAPPED   Overlapped;    LPPER_IO_OPERATION_DATA   perIoData;    LPPER_HANDLE_DATA      perHandleData;    DWORD   SendBytes, RecyBytes;    DWORD   Flags;        while(TRUE)    {        if(GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&perHandleData, (LPOVERLAPPED *)&perIoData, INFINITE) == 0)        {            printf("GetQueuedCompletionStatus() failed with error %d\n", GetLastError());            return 0;        }        if(0 == BytesTransferred)        {            printf("Closing socket %d\n", perHandleData->Socket);            if(SOCKET_ERROR == closesocket(perHandleData->Socket))            {                printf("closesocket() failed with error %d\n"), WSAGetLastError();                return 0;            }            GlobalFree(perHandleData);            GlobalFree(perIoData);            continue;        }                if(0 == perIoData->BytesRecv)        {            perIoData->BytesRecv = BytesTransferred;            perIoData->BytesSend = 0;printf("BytesRecv:%s\n", perIoData->BytesRecv);        }        else        {            perIoData->BytesSend += BytesTransferred;printf("BytesSend:%s\n", perIoData->BytesSend);        }                if(perIoData->BytesRecv > perIoData->BytesSend)        {            ZeroMemory(&(perIoData->Overlapped), sizeof(OVERLAPPED));                        perIoData->DataBuffer.buf = perIoData->Buffer + perIoData->BytesSend;            perIoData->DataBuffer.len = perIoData->BytesRecv - perIoData->BytesSend;                        if(SOCKET_ERROR == WSASend(perHandleData->Socket, &(perIoData->DataBuffer), 1,                &SendBytes, 0, &(perIoData->Overlapped), NULL))            {                if(ERROR_IO_PENDING != WSAGetLastError())                {                    printf("WSASend() failed with error %d\n", WSAGetLastError());                    return 0;                }            }        }        else        {            perIoData->BytesRecv = 0;            Flags = 0;            ZeroMemory(&(perIoData->Overlapped), sizeof(OVERLAPPED));                        perIoData->DataBuffer.len = DATA_BUFSIZE;            perIoData->DataBuffer.buf = perIoData->Buffer;            if(SOCKET_ERROR == WSARecv(perHandleData->Socket, &(perIoData->DataBuffer), 1,                &RecyBytes, &Flags, &(perIoData->Overlapped), NULL))            {                if(ERROR_IO_PENDING != WSAGetLastError())                {                    printf("WSARecv() failed with error %d\n", WSAGetLastError());                    return 0;                }            }        }    }} 


在上述红色处报有问题:
DataBufferf -buf0x00040003 <错误的指针>char *
BytesRecvCXX0030: 错误: 无法计算表达式的值
BytesSendCXX0030: 错误: 无法计算表达式的值


[解决办法]
"perIoData= (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR,sizeof(LPPER_IO_OPERATION_DATA));"
改成如下:
perIoData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA));

[解决办法]
参照我这个看看!
http://blog.csdn.net/jasonM2008/archive/2009/08/13/4441514.aspx

读书人网 >VC/MFC

热点推荐