首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

求SOCKET重叠模型结构定义示例代码.该怎么解决

2012-01-28 
求SOCKET重叠模型结构定义示例代码.............小猪的手把手教你玩转SOCKET模型之重叠文章看了,程序也下

求SOCKET重叠模型结构定义示例代码.............
小猪的手把手教你玩转SOCKET模型之重叠文章看了,程序也下了感觉真的很不错,
但是猪哥的WSASEND部分没有示例,我调起来很困难,各位帮帮忙,最好有完整的示例代码,
谢过!

[解决办法]
WSASend和WSARecv的用法没有太大差别,你可以参考他的WSARecv代码
[解决办法]

C/C++ code
#include "stdafx.h"WSAOVERLAPPED    AcceptOverlapped[10];SOCKET    s,c;int i;WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];WSABUF     DataBuf;      DWORD     dwEventTotal,        // 程序中事件的总数          dwRecvBytes,         // 接收到的字符长度          Flags;               // WSARecv的参数 void CALLBACK WorkRoutine(DWORD error,DWORD BytesTransferred,LPWSAOVERLAPPED Overlapped,                          DWORD InFlags){    DWORD    SendBytes;    DWORD    RecvBytes;    DWORD    Flags;    if(error != 0 || BytesTransferred == 0){    cout<<error<<endl;    closesocket(c);    return;    }    cout<<DataBuf.buf<<endl;    return ;}DWORD WINAPI _AcceptProc(LPVOID lpParameter){    // c = WSASocket(AF_INET,SOCK_STREAM,0,NULL,NULL,WSA_FLAG_OVERLAPPED);    SOCKET    *s = (SOCKET*)lpParameter;    char    buffer[1024];    if(i == 10 ){        cout<<"客户连接已满"<<endl;        shutdown(c,2);        closesocket(c);        i--;        if(i == 0){            cout<<"以清空"<<endl;            return 0;        }        return 0;    }    ZeroMemory(&buffer,sizeof(buffer));    DataBuf.buf = buffer;    DataBuf.len = sizeof(buffer);    while(1){        c = accept(*s,NULL,NULL);    if(c == INVALID_SOCKET){        cout<<"Accept错误"<<endl;        cout<<WSAGetLastError()<<endl;        return 0;    }    ZeroMemory(&AcceptOverlapped[i],sizeof(AcceptOverlapped));    if(i == 0){        if( WSARecv(c,&DataBuf,1,&dwRecvBytes,&Flags,&AcceptOverlapped[i],WorkRoutine) == SOCKET_ERROR){        if(WSAGetLastError() != WSA_IO_PENDING){            cout<<"WSARecv failed with error"<<WSAGetLastError()<<endl;            closesocket(c);            WSACloseEvent(EventArray[dwEventTotal]);            return 0;        }        }    }    i++;    Sleep(500);    }    // CreateThread(NULL,0,_AcceptProc,s,0,NULL);    return 0;}DWORD WINAPI _InterestEventProc(LPVOID lpParameter){    return 0;}int main(int argc, char* argv[]){    WSADATA    wsaData;    SOCKET    s;        sockaddr_in     service,client;    WORD    Version = MAKEWORD(2,2);    DWORD    ThreadID;    EventArray[dwEventTotal] = WSACreateEvent();            //lAcceptOverlapped.hEvent = EventArray[dwEventTotal];    dwEventTotal ++;        WSAStartup(Version,&wsaData);    s = WSASocket(AF_INET,SOCK_STREAM,0,NULL,NULL,WSA_FLAG_OVERLAPPED);    if(s == INVALID_SOCKET){        cout<<"WSASocket错误"<<endl;        cout<<WSAGetLastError()<<endl;        getch();        WSACleanup();        return 0;    }    service.sin_addr.S_un.S_addr   = INADDR_ANY;    service.sin_family = AF_INET;    service.sin_port   = htons(5150);        if( bind(s,(sockaddr*)&service,sizeof(sockaddr_in)) == SOCKET_ERROR){        cout<<"bind 错误"<<endl;        cout<<WSAGetLastError()<<endl;        getch();        WSACleanup();        return 0;    }    listen(s,10);    CreateThread(NULL,0,_AcceptProc,&s,0,NULL);        DWORD    dwIndex = 0, dwBytesTransferred;        while(1){    dwIndex = WSAWaitForMultipleEvents(dwEventTotal,EventArray,false,2000,true);    if(dwIndex == WSA_WAIT_TIMEOUT){        cout<<"超时"<<endl;        continue;    }    if(dwIndex == WAIT_IO_COMPLETION){        cout<<"IO完成"<<endl;        break;    }    dwIndex = dwIndex - WSA_WAIT_EVENT_0;        if(dwIndex == 0){        cout<<"连入一个用户"<<endl;        continue;    }    WSAResetEvent(EventArray[dwIndex]);    WSAGetOverlappedResult(s,&AcceptOverlapped[i],& dwBytesTransferred,false,&Flags);        if(dwBytesTransferred == 0){        cout<<"数据流量0关闭";      closesocket(s);    WSACloseEvent(EventArray[dwIndex]);    // 关闭事件      return 0;    }        Sleep(500);    }        getch();    WSACloseEvent(EventArray[dwEventTotal]);    closesocket(s);    WSACleanup();    return 0;} 


[解决办法]
希望有用,慢慢看
#include "../common/initsock.h" //初始化SOCKET环境,包括一个类,析构时调用WSACleanup

#include <Mswsock.h>
#include <stdio.h>
#include <windows.h>

CInitSock theSock; //实例化

#define BUFFER_SIZE 1024

typedef struct _SOCKET_OBJ
{
SOCKET s;// 套节字句柄
int nOutstandingOps;// 记录此套节字上的重叠I/O数量

LPFN_ACCEPTEX lpfnAcceptEx;// 扩展函数AcceptEx的指针(仅对监听套节字而言)
} SOCKET_OBJ, *PSOCKET_OBJ;

typedef struct _BUFFER_OBJ
{
OVERLAPPED ol;// 重叠结构
char *buff;// send/recv/AcceptEx所使用的缓冲区
int nLen;// buff的长度
PSOCKET_OBJ pSocket;// 此I/O所属的套节字对象

int nOperation;// 提交的操作类型
#define OP_ACCEPT1
#define OP_READ2
#define OP_WRITE3

SOCKET sAccept;// 用来保存AcceptEx接受的客户套节字(仅对监听套节字而言)
_BUFFER_OBJ *pNext;
} BUFFER_OBJ, *PBUFFER_OBJ;

HANDLE g_events[WSA_MAXIMUM_WAIT_EVENTS];// I/O事件句柄数组
int g_nBufferCount;// 上数组中有效句柄数量
PBUFFER_OBJ g_pBufferHead, g_pBufferTail;// 记录缓冲区对象组成的表的地址

// 申请套节字对象和释放套节字对象的函数
PSOCKET_OBJ GetSocketObj(SOCKET s)
{
PSOCKET_OBJ pSocket = (PSOCKET_OBJ)::GlobalAlloc(GPTR, sizeof(SOCKET_OBJ));
if(pSocket != NULL)
{
pSocket->s = s;
}
return pSocket;
}
void FreeSocketObj(PSOCKET_OBJ pSocket)
{
if(pSocket->s != INVALID_SOCKET)
::closesocket(pSocket->s);
::GlobalFree(pSocket);
}

PBUFFER_OBJ GetBufferObj(PSOCKET_OBJ pSocket, ULONG nLen)
{
if(g_nBufferCount > WSA_MAXIMUM_WAIT_EVENTS - 1)
return NULL;

PBUFFER_OBJ pBuffer = (PBUFFER_OBJ)::GlobalAlloc(GPTR, sizeof(BUFFER_OBJ));
if(pBuffer != NULL)
{
pBuffer->buff = (char*)::GlobalAlloc(GPTR, nLen);
pBuffer->ol.hEvent = ::WSACreateEvent();
pBuffer->pSocket = pSocket;
pBuffer->sAccept = INVALID_SOCKET;

// 将新的BUFFER_OBJ添加到列表中
if(g_pBufferHead == NULL)
{
g_pBufferHead = g_pBufferTail = pBuffer;
}
else
{
g_pBufferTail->pNext = pBuffer;
g_pBufferTail = pBuffer;
}
g_events[++ g_nBufferCount] = pBuffer->ol.hEvent;
}
return pBuffer;
}

void FreeBufferObj(PBUFFER_OBJ pBuffer)
{
// 从列表中移除BUFFER_OBJ对象
PBUFFER_OBJ pTest = g_pBufferHead;
BOOL bFind = FALSE;
if(pTest == pBuffer)
{
g_pBufferHead = g_pBufferTail = NULL;
bFind = TRUE;
}
else
{
while(pTest != NULL && pTest->pNext != pBuffer)
pTest = pTest->pNext;
if(pTest != NULL)
{
pTest->pNext = pBuffer->pNext;
if(pTest->pNext == NULL)
g_pBufferTail = pTest;
bFind = TRUE;
}
}
// 释放它占用的内存空间
if(bFind)
{
g_nBufferCount --;
::CloseHandle(pBuffer->ol.hEvent);
::GlobalFree(pBuffer->buff);
::GlobalFree(pBuffer);
}
}

PBUFFER_OBJ FindBufferObj(HANDLE hEvent)
{
PBUFFER_OBJ pBuffer = g_pBufferHead;
while(pBuffer != NULL)
{
if(pBuffer->ol.hEvent == hEvent)
break;
pBuffer = pBuffer->pNext;
}
return pBuffer;
}

void RebuildArray()
{
PBUFFER_OBJ pBuffer = g_pBufferHead;
int i = 1;
while(pBuffer != NULL)
{
g_events[i++] = pBuffer->ol.hEvent;
pBuffer = pBuffer->pNext;
}
}

BOOL PostAccept(PBUFFER_OBJ pBuffer)
{
PSOCKET_OBJ pSocket = pBuffer->pSocket;
if(pSocket->lpfnAcceptEx != NULL)
{
// 设置I/O类型,增加套节字上的重叠I/O计数
pBuffer->nOperation = OP_ACCEPT;
pSocket->nOutstandingOps ++;

// 投递此重叠I/O
DWORD dwBytes;
pBuffer->sAccept = 
::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);


BOOL b = pSocket->lpfnAcceptEx(pSocket->s, 
pBuffer->sAccept,
pBuffer->buff, 
BUFFER_SIZE - ((sizeof(sockaddr_in) + 16) * 2),
sizeof(sockaddr_in) + 16, 
sizeof(sockaddr_in) + 16, 
&dwBytes, 
&pBuffer->ol);
if(!b)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
return FALSE;
}
return TRUE;
}
return FALSE;
};

BOOL PostRecv(PBUFFER_OBJ pBuffer)
{
// 设置I/O类型,增加套节字上的重叠I/O计数
pBuffer->nOperation = OP_READ;
pBuffer->pSocket->nOutstandingOps ++;

// 投递此重叠I/O
DWORD dwBytes;
DWORD dwFlags = 0;
WSABUF buf;
buf.buf = pBuffer->buff;
buf.len = pBuffer->nLen;
if(::WSARecv(pBuffer->pSocket->s, &buf, 1, &dwBytes, &dwFlags, &pBuffer->ol, NULL) != NO_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
return FALSE;
}
return TRUE;
}

热点排行