跨平台的游戏客户端Socket封装
依照惯例,先上代码:
// 发送消息bSucSend = m_pSocket->SendMsg(buf, nLen);// 接收消息处理(放到游戏主循环中,每帧处理)if (!m_pSocket) {return;}if (!m_pSocket->Check()) {m_pSocket = NULL;// 掉线了onConnectionAbort();return;}// 发送数据(向服务器发送消息)m_pSocket->Flush();// 接收数据(取得缓冲区中的所有消息,直到缓冲区为空)while (true){char buffer[_MAX_MSGSIZE] = { 0 };int nSize = sizeof(buffer);char* pbufMsg = buffer;if(m_pSocket == NULL){break;}if (!m_pSocket->ReceiveMsg(pbufMsg, nSize)) {break;}while (true){MsgHead* pReceiveMsg = (MsgHead*)(pbufMsg);uint16dwCurMsgSize = pReceiveMsg->usSize;//CCLOG("msgsize: %d", dwCurMsgSize);if((int)dwCurMsgSize > nSize || dwCurMsgSize <= 0) {// broken msgbreak;}CMessageSubject::instance().OnMessage((const char*)pReceiveMsg, pReceiveMsg->usSize);pbufMsg+= dwCurMsgSize;nSize-= dwCurMsgSize;if(nSize <= 0) {break;}}}这里展示这个,目的并不是说这个封装有多么优异,多么高科技,多么牛x。 恰恰是想表达它的简单。 这个简单的封装完全可以胜任一个mmo客户端的消息底层(注意是客户端,服务器对消息底层的性能要求要远远大于客户端),甚至是魔兽世界这类的大型mmo都可以用这么一个小的封装来做消息底层。
对于游戏客户端消息底层的要求非常简单,根本不需要boost::asio什么的开源库。
1、非阻塞模型,这样我才放心把消息处理放到主线程,多线程处理消息其实很浪费。不知道得多大型的mmo才会用到。
2、消息接收缓存处理,避免大消息被截掉。
3、没了,剩下的一些特殊处理应该是上层逻辑来考虑的。比如掉线重连等。