您的位置:首页 > 其它

最近有点时间-赶紧学习,好久没有写东西了

2011-09-02 15:48 621 查看
自从每天跟踪项目,问题1,问题2,需求1,需求2的,满脑子都是

方案,策略,开发进度,闲暇下来做一些代码,真是愉快的享受啊

感谢黑色太阳的相信,我参与了directUI项目的管理员,并且参与项目初期的框架和设计工作

目前项目已经开始做起来了。希望后期可以做很好的扩展和应用, 事实证明Ui对我的兴趣不大

。答应朋友的事情一定要做完。项目余下的工作就是task分发,Branch管理,以及松散项目的规划

我们同时lauch了另外一个项目音频服务器。 使用windows IOCP 模型

IOCP 经过这几天的研究似乎没有想象的那么难, 模型是参考了

《windows网络和程序设计》

微软的IOCP介绍

有这2篇,写一个小模型还是很容易的

//按照这个设计写的



// IOCPSvrMgr.h: interface for the CIOCPSvrMgr class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_IOCPSVRMGR_H__07297532_F74F_4EF7_9BD3_5F1E6C4B1087__INCLUDED_)

#define AFX_IOCPSVRMGR_H__07297532_F74F_4EF7_9BD3_5F1E6C4B1087__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include <winsock2.h>

typedef struct _PER_HANDLE_DATA // per-handle数据

{

SOCKET s;
// 对应的套节字句柄

sockaddr_in addr;// 客户方地址

} PER_HANDLE_DATA, *PPER_HANDLE_DATA;

#define BUFFER_SIZE 1024

typedef struct _PER_IO_DATA // per-I/O数据

{

OVERLAPPED ol;// 重叠结构

char buf[BUFFER_SIZE];// 数据缓冲区

int nOperationType;// 操作类型

#define OP_READ 1

#define OP_WRITE 2

#define OP_ACCEPT 3

} PER_IO_DATA, *PPER_IO_DATA;

class CIOCPSvrMgr

{

public:

void networkUninitial();

BOOL StartSocketTask();

void CreateServerThread();

BOOL CreateCompleteIO();

HANDLE GetCompletionHandle();

BOOL InitNetwork();

CIOCPSvrMgr();

virtual ~CIOCPSvrMgr();

private:

HANDLE m_hCompletion;

};

#endif // !defined(AFX_IOCPSVRMGR_H__07297532_F74F_4EF7_9BD3_5F1E6C4B1087__INCLUDED_)

////////////////// 实现文件////////////////////////////////////////////////////////////////////////////////////

// IOCPSvrMgr.cpp: implementation of the CIOCPSvrMgr class.

//

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "IOCPSvrMgr.h"

//////////////////////////////////////////////////////////////////////

//need update to cfg.ini

#define nPort 5667

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

DWORD WINAPI ServerWorkingThread(LPVOID lpParam)

{

//这段代码有问题,因为如果包多的话

// PPER_HANDLE_DATA pPerHandle;

// PPER_IO_DATA pPerIO;

// 这2个值,将会出现数据不完整,下一个版本修正

// 得到完成端口对象句柄

HANDLE hCompletion = (HANDLE)lpParam;

OutputDebugString("ServerThread Processor\n");

DWORD dwTrans;

PPER_HANDLE_DATA pPerHandle;

PPER_IO_DATA pPerIO;

while(TRUE)

{

// 在关联到此完成端口的所有套节字上等待I/O完成

OutputDebugString("wait GetQueuedCompletionStatus");

SetLastError(0);

BOOL bOK = ::GetQueuedCompletionStatus(hCompletion,

&dwTrans, (LPDWORD)&pPerHandle, (LPOVERLAPPED*)&pPerIO, WSA_INFINITE);

if(!bOK)
// 在此套节字上有错误发生

{

OutputDebugString("关闭当前连接\n");

if ( pPerHandle != NULL && pPerHandle->s != INVALID_SOCKET )

{

::closesocket(pPerHandle->s);

::GlobalFree(pPerHandle);

::GlobalFree(pPerIO);

pPerHandle->s=INVALID_SOCKET;

pPerHandle = NULL;

pPerIO = NULL;

OutputDebugString("继续下一个队列状态读取");

}

continue;

}

if(dwTrans == 0 &&// 套节字被对方关闭

(pPerIO->nOperationType == OP_READ || pPerIO->nOperationType == OP_WRITE))

{

OutputDebugString("套节字被对方关闭 10 ");

if ( pPerHandle != NULL && pPerHandle->s != INVALID_SOCKET)

{

::closesocket(pPerHandle->s);

::GlobalFree(pPerHandle);

::GlobalFree(pPerIO);

pPerHandle->s=INVALID_SOCKET;

pPerHandle = NULL;

pPerIO = NULL;

}

continue;

}

OutputDebugString("11开始处理请求\n");

switch(pPerIO->nOperationType)// 通过per-I/O数据中的nOperationType域查看什么I/O请求完成了

{

case OP_READ:
// 完成一个接收请求

{

pPerIO->buf[dwTrans] = '\0';

OutputDebugString(pPerIO -> buf);

// 继续投递接收I/O请求

WSABUF buf;

buf.buf = pPerIO->buf ;

buf.len = BUFFER_SIZE;

pPerIO->nOperationType = OP_READ;

DWORD nFlags = 0;

OutputDebugString("12\n");

if (pPerHandle != NULL && pPerHandle->s != INVALID_SOCKET )

{

::WSARecv(pPerHandle->s, &buf, 1, &dwTrans, &nFlags, &pPerIO->ol, NULL);

OutputDebugString("12++++++++++++++++++++\n");

}

if ( pPerHandle!= NULL )

{

if (pPerHandle->s != INVALID_SOCKET )

{

::WSASend(pPerHandle->s, &buf, 1, &dwTrans, nFlags, &pPerIO->ol, NULL);

XAMgrTrace("%d", WSAGetLastError());

}

}

}

break;

case OP_WRITE:

{

// WSABUF buf;

// buf.buf = pPerIO->buf ;

// buf.len = BUFFER_SIZE;

// pPerIO->nOperationType = OP_READ;

// DWORD nFlags = 0;

// ::WSASend(pPerHandle->s, &buf, 1, &dwTrans, nFlags, &pPerIO->ol, NULL);

}

break;

case OP_ACCEPT:

{

}

break;

}

}

return 0;

};

DWORD WINAPI ServerAcceptThread(LPVOID lpParam)

{

// 得到完成端口对象句柄

HANDLE m_hCompletion = (HANDLE)lpParam;

OutputDebugString("ServerAcceptThread Processor\n");

// 创建监听套节字,绑定到本地地址,开始监听

SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, 0);

SOCKADDR_IN si;

si.sin_family = AF_INET;

si.sin_port = ::ntohs(nPort);

si.sin_addr.S_un.S_addr = INADDR_ANY;

::bind(sListen, (sockaddr*)&si, sizeof(si));

::listen(sListen, 5);

while (TRUE)

{

OutputDebugString("Wait for connect...");

SOCKADDR_IN saRemote;

int nRemoteLen = sizeof(saRemote);

SOCKET sNew = ::accept(sListen, (sockaddr*)&saRemote, &nRemoteLen);

// 接受到新连接之后,为它创建一个per-handle数据,并将它们关联到完成端口对象

PPER_HANDLE_DATA pPerhandle = (PPER_HANDLE_DATA)::GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA) );

pPerhandle->s = sNew;

memcpy(&pPerhandle->addr, &saRemote, nRemoteLen);

::CreateIoCompletionPort((HANDLE)pPerhandle->s, m_hCompletion, (DWORD)pPerhandle, 0);

OutputDebugString("Accept connect , assigned a CreateIoCompletionPort \n");

// 投递一个接收请求

PPER_IO_DATA pPerIO = (PPER_IO_DATA)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA));

pPerIO->nOperationType = OP_READ;

WSABUF buf;

buf.buf = pPerIO->buf;

buf.len = BUFFER_SIZE;

DWORD dwRecv;

DWORD dwFlags = 0;

OutputDebugString(" Mail a request!!! \n");

::WSARecv(pPerhandle->s, &buf, 1, &dwRecv, &dwFlags, &pPerIO->ol, NULL);

}

return 0;

}

CIOCPSvrMgr::CIOCPSvrMgr()

{

}

CIOCPSvrMgr::~CIOCPSvrMgr()

{

}

BOOL CIOCPSvrMgr::InitNetwork()

{

OutputDebugString("InitNetwork");

BYTE minorVer = 0x02;

BYTE majorVer = 0x02;

WSADATA wsaData;

WORD sockVersion = MAKEWORD(minorVer, majorVer);

if(::WSAStartup(sockVersion, &wsaData) == 0)

{

return TRUE;

}

return FALSE;

}

HANDLE CIOCPSvrMgr::GetCompletionHandle()

{

return m_hCompletion;

}

BOOL CIOCPSvrMgr::CreateCompleteIO()

{

OutputDebugString("CreateCompleteIO function");

m_hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);

if ( m_hCompletion != INVALID_HANDLE_VALUE )

{

return TRUE;

}

return FALSE;

}

void CIOCPSvrMgr::CreateServerThread()

{

::CreateThread(NULL, 0, ServerWorkingThread, (LPVOID)m_hCompletion, 0, 0);

}

BOOL CIOCPSvrMgr::StartSocketTask()

{

//////////////////////////////////////////

::CreateThread(NULL, 0, ServerAcceptThread, (LPVOID)m_hCompletion, 0, 0);

//////////////////////////////////////////

return TRUE;

}

void CIOCPSvrMgr::networkUninitial()

{

::WSACleanup();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: