重叠I/O,只用自己写过,才是自己的东西


本人菜鸟,大神飘过。。

如有什么不对的地方,请大家多多指正过来。再次感谢!!!


就我所知的异步通讯有:

SELECT,WSAAynsSelect,,WSAEventSelect, 重叠I/O,完成端口。


SELECT 的核心思想就是你要懂fd_set结构。 而对此结构的几个操作方法:FD_ZERO, FD_SET和FD_ISSET。

其大概的流程应该是: 

1)申明一个fd_set对象,如 fd_set fd1;

2)在循环中,调用FD_ZERO(fd1)。从文字可以看出,主要作用是把结构清零!

3)调用FD_SET(s,&fd1)。主要作用是把我们的套接字s放到结构体中。

4)调用select函数。检查是否有读写事件。。

5)调用FD_ISSET(s,fd1),查看是否有读写事件。如果为真,则有事件,操作recv/send


WSAAynsSelect的核心思想就是系统帮我监听我们要求监听的事件,然后用WINDOWS消息告诉我们。

具体可以参考:http://blog.csdn.net/yanheifeng715000/article/details/6593303


WSAEventSelect的核心思想就是把每个套接字绑定一个EVENT事件,当对应的套接字有读写操作时,就会触发对应的事件。然后进行操作!

具体参考:http://blog.csdn.net/wanjingwei/article/details/4306609


而重叠I/O的核心事件是利用OVERLAPPED结构,而该对象我们主要关心的是hEvent成员。该成员绑定一个事件,可用WSACreateEvent、CreateEvent。

每个对象套接字都会绑定一个OVERLAPPED结构,当有读写事件时,hEvent为有信号状态。


可用代码在:http://download.csdn.net/detail/magedhenary/7519573

好了,其实我并不太会说,直接上代码:

class LappedSocket
{
public:
LappedSocket()
: m_sock(NULL)
, m_pbuf(NULL)
, m_len(0)
, m_oper(OPER_SOCKET_EMPTY){}
LappedSocket(SOCKET sock, int nlen)
:m_oper(OPER_SOCKET_EMPTY){
m_sock = sock;
m_pbuf = new char[nlen];
memset(m_pbuf, 0, nlen);
m_len = nlen;
m_overlapped.hEvent = ::WSACreateEvent();
}


~LappedSocket(){
if (m_sock != NULL){
closesocket(m_sock);
m_sock = NULL;
}

if (m_pbuf != NULL){
delete[] m_pbuf;
m_pbuf = NULL;
}

m_len = 0;
m_oper = OPER_SOCKET_EMPTY;
}


bool operator ==(const LappedSocket& socket){
if (this->m_sock == socket.m_sock
&& this->m_len == socket.m_len
&& this->m_oper == socket.m_oper
&& strcmp(this->m_pbuf, socket.m_pbuf) == 0)
return true;

return false;
}


public:
int RecvLapped();
int SendLapped();


public:
SOCKET m_sock; // socket information
OVERLAPPED m_overlapped;// bind i/o
char* m_pbuf;// buffer
int m_len;// length
int m_oper;// operation
};



该类主要是为了封装SOCKET,与OVERLAPPED结构。


class LappedServer
{
public:
LappedServer(){
m_sockListen = NULL;
m_nport = 0;
m_blisten = false;
memset(m_saddr, 0, 256);
}


~LappedServer(){ CloseServer(); }

void CloseServer();
void StartServer(int nport, char* paddr, int nlisten=5);

protected:
bool CreateServer();
static unsigned _stdcall _StartServer(void* pinfor);


private:
SOCKET m_sockListen;
int m_nlisten;
int m_nport;
char m_saddr[256];


bool m_blisten;
HANDLE m_handle;
};



该类主要封装一个服务器,调用StartServer函数即可启动服务器监听。

class ManagerSocket
{
public:
ManagerSocket();
~ManagerSocket();


public:
int GetSize(){
return m_lsSock.size();
}


bool InsertSocket(SOCKET sock);


bool PostRecv(LappedSocket* psock);
bool PostSend(LappedSocket* psock);


void StartThread();


protected:
void ResetEventArray();


// thread operation
static unsigned _stdcall StartOperation(void* pinfor);
bool OperationSocket(int index);




public:
deque<LappedSocket*> m_lsSock;
vector<HANDLE>m_lsEvent;
HANDLE m_hAcceptEvent;


bool m_bThread;
HANDLE m_threadOper;


};



该类主要是管理服务器监听到的SOCKET。查看每个SOCKET的读写事件。。


可用代码在:http://download.csdn.net/detail/magedhenary/7519573


今天到此为止!改天在整整完成端口的类出来跟大家讨论讨论。


技术有限,如有什么好的建议欢迎大家跟我交流,指正!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值