#include <winsock2.h>
#include <iostream>
#include <vector>
#include <mswsock.h>
using namespace std;
#define PORT 4567
#define MAXBUFFER 1024
#pragma comment(lib, "ws2_32.lib")
typedef struct _SOCKOBJ
{
int nOperationType;
SOCKET sAccept;
OVERLAPPED ol;
char Buff[MAXBUFFER];
char * lpBuff;
DWORD dwLen;
_SOCKOBJ()
{
ZeroMemory(&ol,sizeof(OVERLAPPED));
ZeroMemory(Buff,sizeof(MAXBUFFER));
nOperationType = 0;
sAccept = INVALID_SOCKET;
lpBuff = Buff;
dwLen = 0;
ol.hEvent = WSACreateEvent();
}
}* PSOCKOBJ,SOCKOBJ;
DWORD dwTotal = 0,dwIndex=0;
vector<SOCKOBJ> mSKObj;
HANDLE events[WSA_MAXIMUM_WAIT_EVENTS];
void InitSock()
{
WSADATA WSAData;
LPFN_ACCEPTEX lpfnAcceptEx;
::WSAStartup(MAKEWORD(2,2),&WSAData);
SOCKET sListen = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
sockaddr_in in_service;
::ZeroMemory(&in_service,sizeof(sockaddr_in));
in_service.sin_family = AF_INET;
in_service.sin_port = ::ntohs(4567);
in_service.sin_addr.S_un.S_addr = ::inet_addr("192.168.1.102");
int ret = bind(sListen,(sockaddr*)&in_service,sizeof(sockaddr_in));
if(ret == INVALID_SOCKET)
{
cout << "bind error" << "\n";
}
listen(sListen,5);
GUID GuidAcceptEx = WSAID_ACCEPTEX;
DWORD dwBytes;
WSAIoctl(sListen,SIO_GET_EXTENSION_FUNCTION_POINTER,
&GuidAcceptEx,sizeof(GuidAcceptEx),&lpfnAcceptEx,sizeof(lpfnAcceptEx),&dwBytes,NULL,NULL);
for(int i=0;i<5;i++)
{
PSOCKOBJ obj = new SOCKOBJ();
obj->nOperationType = 1;
obj->sAccept = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
lpfnAcceptEx(sListen,obj->sAccept,obj->lpBuff,
MAXBUFFER - 2*(sizeof(sockaddr_in)+16),
sizeof(sockaddr_in)+16,
sizeof(sockaddr_in)+16,
&obj->dwLen,
&obj->ol);
mSKObj.push_back(*obj);
events[dwTotal++] = obj->ol.hEvent;
}
while(true)
{
// dwIndex 每次都回傳 0
dwIndex == ::WSAWaitForMultipleEvents(dwTotal,events,FALSE,WSA_INFINITE,FALSE);
cout << "code:" << GetLastError() << ",retrun:" << dwIndex << "\n";
if(dwIndex == WSA_WAIT_FAILED)
{
cout <<"WSAWaitForMultipleEvents failed! \n";
}
dwIndex = dwIndex - WSA_WAIT_EVENT_0;
for(int i=dwIndex;i<dwTotal;i++)
{
dwIndex = WSAWaitForMultipleEvents(1,&events[i],FALSE,0,FALSE);
if(dwIndex == WSA_WAIT_TIMEOUT)
{
continue;
}
::WSAResetEvent(events[i]);
DWORD dwTrans=0;
DWORD dwFlags=0;
SOCKOBJ obj = mSKObj.at(i);
// bRet 回傳總是False 并且 GetLastError == 996
BOOL bRet = ::WSAGetOverlappedResult(obj.sAccept, &obj.ol, &dwTrans, FALSE, &dwFlags);
cout << "接收資料長度:" <<dwTrans << "\n";
if(!bRet)
{
DWORD err = ::GetLastError();
cout << "WSAGetOverlappedResult failed! \n";
}
}
}
}
void main()
{
InitSock();
}
------------------------
// dwIndex 每次都回傳 0
// bRet 回傳總是False 并且 GetLastError == 996
uj5u.com熱心網友回復:
996 —WSA_IO_INCOMPLETE重疊I / O 事件物件未處于傳信狀態。這個Wi n 3 2 錯誤也和重疊I / O 操作密切相關,在呼叫W S A G e t Ov e r l a p p e d R e s u l t s 函式的時候產生,指出重疊I / O 操作尚未完成。
uj5u.com熱心網友回復:
我知道是重疊I / O 操作尚未完成 。但是具體是什么I / O 操作未完成。什么地方引起的錯誤。
uj5u.com熱心網友回復:
BOOL WSAAPI WSAGetOverlappedResult(__in SOCKET s,
__in LPWSAOVERLAPPED lpOverlapped,
__out LPDWORD lpcbTransfer,
__in BOOL fWait,
__out LPDWORD lpdwFlags
);
Parameters
s
A descriptor identifying the socket. This is the same socket that was specified when the overlapped operation was started by a call to WSARecv, WSARecvFrom, WSASend, WSASendTo, or WSAIoctl.
lpOverlapped
A pointer to a WSAOVERLAPPED structure that was specified when the overlapped operation was started. This parameter must not be a NULL pointer.
lpcbTransfer
A pointer to a 32-bit variable that receives the number of bytes that were actually transferred by a send or receive operation, or by WSAIoctl. This parameter must not be a NULL pointer.
fWait
A flag that specifies whether the function should wait for the pending overlapped operation to complete. If TRUE, the function does not return until the operation has been completed. If FALSE and the operation is still pending, the function returns FALSE and the WSAGetLastError function returns WSA_IO_INCOMPLETE. The fWait parameter may be set to TRUE only if the overlapped operation selected the event-based completion notification.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/134106.html
標籤:網絡編程
上一篇:vs2010怎么打包mfc
下一篇:MFC SDI視窗非客戶區變花
