读书人

堆叠 io 有一个函数如果失败那么需

发布时间: 2012-09-05 15:19:35 作者: rapoo

重叠 io 有一个函数,如果失败,那么需要再次调用,它叫什么啊?
重叠io winscock中的

今天看了msdn, 后来出去办点事,回来后,就发现再也找不到这个函数,找了一晚上,也没有找到。悲剧不?


问题2:

在大家的基础上和msdn的帮助, 我已经修改了代码,发现收到的数据会乱码,而且不断的输入,似乎是死循环的方式

打印数据,崩溃了

C/C++ code
// NetWork.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include"InitSock.h"#include <Winsock2.h>#include <Windows.h>#include <process.h>#pragma comment(lib, "WS2_32.lib")#define MAX_BUFFER    256#define MAX_TIMEOUT 4000typedef enum _OPERATION_INFO{    OP_NULL,    OP_ACCEPT,    OP_READ,    OP_WRITE}OPERATIONINFO;typedef struct _OVERLAPPED_INFO_{    public:    _OVERLAPPED_INFO_()    {        Clean();    }    ~_OVERLAPPED_INFO_()    {        Clean();    }protected:    void Clean()    {        ol.hEvent = NULL;        sock = INVALID_SOCKET;        wsaBuf.buf = szBuf;        wsaBuf.len = MAX_BUFFER;        memset(szBuf, 0, sizeof(szBuf));    }public:    WSAOVERLAPPED ol;    SOCKET sock;    WSABUF wsaBuf;    char szBuf[MAX_BUFFER];}OVERLAPPEDINFO, *POVERLAPPEDINFO;WSAEVENT g_event[WSA_MAXIMUM_WAIT_EVENTS] = {0};OVERLAPPEDINFO* g_ol[WSA_MAXIMUM_WAIT_EVENTS] = {0};int g_nIndex = 0;BOOL g_bExitThread = FALSE;unsigned __stdcall ThreadProc(LPVOID lParam);CInitSock  g_InitSock;SOCKET g_sListen ;#include <stdio.h>#include <process.h>int main(){        g_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if(INVALID_SOCKET == g_sListen)    {        printf("socket failed with error code: %d/n", WSAGetLastError());                return EXIT_FAILURE;    }    SOCKADDR_IN addr = {0};    addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");    addr.sin_family = AF_INET;    addr.sin_port = htons(5050);    if(SOCKET_ERROR == bind(g_sListen, (LPSOCKADDR)&addr, sizeof(addr)))    {        printf("bind failed with error code: %d/n", WSAGetLastError());        closesocket(g_sListen);        return EXIT_FAILURE;    }    if(SOCKET_ERROR == listen(g_sListen, 5))    {        printf("listen failed with error code: %d/n", WSAGetLastError());        closesocket(g_sListen);        return EXIT_FAILURE;    }    //g_ol[g_nIndex] = new OVERLAPPEDINFO;    //g_ol[g_nIndex]->sock = g_sListen;    //g_event[g_nIndex] = g_ol[g_nIndex]->ol.hEvent = WSACreateEvent();    //g_nIndex++;    u_long argp=1;    ioctlsocket(g_sListen,FIONBIO,&argp);    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL);    if(NULL == hThread)    {        printf("_beginthreadex failed with error code: %d/n", GetLastError());        closesocket(g_sListen);        return EXIT_FAILURE;    }        printf("Server start listen and wait for client to connect .../n");    WaitForSingleObject(hThread, INFINITE);    g_bExitThread = TRUE; // Exit thread.    CloseHandle(hThread);    return 0;}unsigned __stdcall ThreadProc(LPVOID lParam){    while(!g_bExitThread)    {        DWORD dwFlags, dwTrans, BytesTransferred;        dwFlags=0;        SOCKADDR_IN remote = {0};        int len = sizeof(remote);        SOCKET sNew=accept(g_sListen,(LPSOCKADDR)&remote,&len);        if(INVALID_SOCKET !=sNew)        {            g_ol[g_nIndex]=new OVERLAPPEDINFO;            g_ol[g_nIndex]->sock=sNew;            g_event[g_nIndex]=g_ol[g_nIndex]->ol.hEvent=WSACreateEvent();            g_nIndex++;                    }        for(int nPos=0; nPos<g_nIndex; nPos++)        {            //投递请求            if(SOCKET_ERROR == WSARecv(g_ol[nPos]->sock, &(g_ol[nPos]->wsaBuf), 1, &dwTrans, &dwFlags, &(g_ol[nPos]->ol), NULL))            {                if(ERROR_IO_PENDING != WSAGetLastError())                {                    closesocket(g_ol[nPos]->sock);                    printf("WSARecv failed with error code: %d/n", WSAGetLastError());                    continue;                }            }                //等待事件对象触发             DWORD nRet = WSAWaitForMultipleEvents(1, &g_event[g_nIndex], TRUE, MAX_TIMEOUT, FALSE);            if(WSA_WAIT_FAILED == nRet || WSA_WAIT_TIMEOUT == nRet)            {                continue;            }            //查询            BOOL bResult =WSAGetOverlappedResult(g_ol[nPos]->sock,&(g_ol[nPos]->ol), &BytesTransferred, FALSE,                &dwFlags);            if (bResult == FALSE)            {                wprintf(L"WSAGetOverlappedResult failed with error = %d\n", WSAGetLastError());            }            //-----------------------------------------            // If the connection has been closed, close the accepted socket            if (BytesTransferred == 0)             {                closesocket(g_ol[nPos]->sock);                WSACloseEvent(g_event[nPos]);            }            else            {                printf("%s\n",g_ol[nPos]->szBuf);            }        }        }    printf("Server to exit ... /n");    return 0;} 




BOOL WSAAPI WSAGetOverlappedResult(
_In_ SOCKET s,
_In_ LPWSAOVERLAPPED lpOverlapped,
_Out_ LPDWORD lpcbTransfer,
_In_ BOOL fWait,
_Out_ LPDWORD lpdwFlags //这个参数,到底如何正确使用!!!! msdn说的过于含糊了,我发现其的值貌似是WSARecv的一个参数的值,是不是这样的啊???
);





[解决办法]
http://www.cnblogs.com/my_life/articles/1982091.html
可以看看文章,能增加你的理解.
[解决办法]
几年前封装过overlapped io socket模型.很高效的异步.
下面给你我学习用的例子. 这个是基于完成例程的重叠io.


C/C++ code
#include "stdafx.h"#include <iostream>#include <tchar.h>#include <WINSOCK2.H>#include <stdio.h>#pragma comment(lib, "ws2_32.lib")#define MSGSIZE 1024#define PORT 10000typedef struct{ WSAOVERLAPPED overlap;   WSABUF        Buffer; char           szMessage[MSGSIZE];// DWORD         NumberOfBytesRecvd; DWORD         Flags;  SOCKET        sClient;}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;void CALLBACK CompletionROUTINE(DWORD dwError,                                DWORD cbTransferred,                                LPWSAOVERLAPPED lpOverlapped,                                DWORD dwFlags){  LPPER_IO_OPERATION_DATA lpPerIOData = (LPPER_IO_OPERATION_DATA)lpOverlapped;  SOCKET sock=lpPerIOData->sClient;  if (dwError != 0 || cbTransferred == 0) {    // Connection was closed by client    closesocket(lpPerIOData->sClient);      printf("一个客户退出 socket id:%d\r\n",lpPerIOData->sClient);   //释放客户对应的结构内存    delete lpPerIOData;    lpPerIOData=NULL; }  else  {      printf("recv sock:%d size:%d\n",sock,cbTransferred);     //在这里处理接收的数据,然后发送...并重置这个客户socket异步接收操作..    //lpPerIOData->szMessage[cbTransferred] = '\0';    //send(lpPerIOData->sClient, lpPerIOData->szMessage, cbTransferred, 0);        // Launch another asynchronous operation    memset(&lpPerIOData->overlap, 0, sizeof(WSAOVERLAPPED));    lpPerIOData->Buffer.len = MSGSIZE;    lpPerIOData->Buffer.buf = lpPerIOData->szMessage;        WSARecv(lpPerIOData->sClient,      &lpPerIOData->Buffer,      1,      &lpPerIOData->NumberOfBytesRecvd,      &lpPerIOData->Flags,      &lpPerIOData->overlap,      CompletionROUTINE);  }}void GetError(DWORD error)    //返回错误信息{    switch(error)    {    case WSANOTINITIALISED:        printf("初始化错误\r\n");        break;    case WSAENOTCONN:            printf("对方没有启动\r\n");        break;    case WSAEWOULDBLOCK :        printf("对方已经关闭\r\n");        break;    case WSAECONNREFUSED:        printf("对方没打开端口\r\n");        break;    case WSAENOTSOCK:        printf("在一个非套接字上尝试了一个操作\r\n");        break;    case WSAEADDRINUSE:        printf("特定的地址已在使用中\r\n");        break;    case WSAECONNRESET:        printf("与主机的连接被关闭\r\n");        break;    default:        printf("一般错误,连接出现异常断开\r\n");        }}int main(){  WSADATA     wsaData;  SOCKET      sListen;  SOCKADDR_IN local, client;  int         iaddrSize = sizeof(SOCKADDR_IN);   // Initialize Windows Socket library   int ret= WSAStartup(0x0202, &wsaData);    if(ret!=0)     {        printf("socket WSAStartup Error!\r\n");            return 1;    }else printf("socket WSAStartup OK!\r\n");       // Create listening socket   sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);   local.sin_family = AF_INET;   local.sin_port = htons(PORT);     //绑定一个套接字到本机的地址   ret= bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));    if(ret == SOCKET_ERROR)    {    //绑定错误        printf("Binding Error\r\n");        return FALSE;    }     // Listen    ret=  listen(sListen, 3);    if(ret==SOCKET_ERROR)    {        printf("listen失败 错误原因:",ret=WSAGetLastError());        GetError(ret);        return false ;    }    printf("listen OK!\r\nWaiting Client Connect\n");      while (TRUE)  {    // Accept a connection     LPPER_IO_OPERATION_DATA lpPerIOData = NULL;    SOCKET g_sNewClientConnection;    g_sNewClientConnection = accept(sListen, (struct sockaddr *)&client, &iaddrSize);    // Launch an asynchronous operation for new arrived connection        lpPerIOData=new PER_IO_OPERATION_DATA();      lpPerIOData->Buffer.len = MSGSIZE;      lpPerIOData->Buffer.buf = lpPerIOData->szMessage;      lpPerIOData->sClient = g_sNewClientConnection;           ret= WSARecv(lpPerIOData->sClient,//客户socket        &lpPerIOData->Buffer,  //存放接收数据的        1, //dwBufferCount  [in] Number of WSABUF structures in the lpBuffers array.         &lpPerIOData->NumberOfBytesRecvd,//存放接收数据的字节数        &lpPerIOData->Flags,        &lpPerIOData->overlap,        CompletionROUTINE);    //如果接收的数据超过MSGSIZE 系统就会多次调用CompletionROUTINE,直到接收完..        printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));  }} 

读书人网 >VC/MFC

热点推荐