SelGate服务器
注:客户端从LoginSvr服务器得到SelGate服务器IP之后,连接SelGate服务器,进行角
色创建,删除,选择操作,然后发送数据到DBSrv服务器。
g_ssock  Local7100客户端登陆端口
g_csock Remote5100发送到DBSrv服务器上的套接字
1.首先从SelGate.cpp WinMain分析:
1) CheckAvailableIOCP : 检查是不是NT,2000的系统(IOCP)
2) InitInstance: 初始化界面,加载WSAStartup
3) MainWndProc窗口回调函数.
2.MainWndProc.CPP中分析回调函数MainWndProc
switch (nMsg)
{
case _IDM_CLIENTSOCK_MSG:
case WM_COMMAND:
case WM_CLOSE:
1)_IDM_CLIENTSOCK_MSG 消息:
处理与SelGate回调通讯事件。
调用:OnClientSockMsg,该函数是一个回调函数:
当启动服务之后,ConnectToServer函数将(_IDM_CLIENTSOCK_MSG消息 FD_CONNECT|FD_READ|FD_CLOSE)传入WSAAsyncSelect函数。在与hWnd窗口句柄对应的窗口例程中以Windows消息的形式接收网络事件通知。函数OnClientSockMsg,主要完成与DBSrv服务器之间的通信(心跳,转发客户端数据包等)
switch (WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT:
case FD_CLOSE:
case FD_READ:
FD_CONNECT:(重新连接情况)
A. CheckSocketError返回正常时:
a). ConnectToServer函数首先在服务启动的时候执行一次。回调
FD_CONNECT
b).连接DBSrv时,开启ThreadFuncForMsg线程,把从客户端发送的数据(g_xMsgQueue, FD_READ事件读到的DBSrv服务器发来的数据)投递I/O,利用IOCP模型,发送到客户端。SleepEx挂起线程,至到一个I/O 完成回调函数被调用。一个异步过程调用排队到此线程。
ThreadFuncForMsg线程检测(从DBSrv收到的g_xMsgQueue数据包-心跳,处理包)。i/o 投递,利用IOCP发送给客户端。
if (nSocket = AnsiStrToVal(pszFirst + 1)) //得到socket
WSASend((SOCKET)nSocket, &Buf, 1, &dwSendBytes, 0, NULL, NULL);
c).终止定时器_ID_TIMER_CONNECTSERVER
KillTimer(g_hMainWnd, _ID_TIMER_CONNECTSERVER);
d).设置_ID_TIMER_KEEPALIVE定时器 (心跳数据包)
SetTimer(g_hMainWnd, _ID_TIMER_KEEPALIVE
调用定时器回调函数OnTimerProc: 定时发关心跳数据包到DBSrv服务器。SendExToServer(PACKET_KEEPALIVE);
B. 如果socket断开,设置_ID_TIMER_CONNECTSERVER定时器
ConnectToServer尝试重新连接服务器。
_ID_TIMER_CONNECTSERVER, (TIMERPROC)OnTimerProc);
FD_CLOSE:
断开SOCKET连接,OnCommand(IDM_STOPSERVICE, 0); 回调函数处理IDM_STOPSERVICE。
case FD_READ:
接收DBSrv服务器发送的数据包(心跳,登陆验证,selCur服务器地址),把数据加入缓冲区(g_xMsgQueue)中。
WM_COMMAND:
IDM_STARTSERVICE: 启动服务(IOCP模型Server响应客户端请求)
IDM_STOPSERVICE: 停止服务(IOCP模型Server)
WM_CLOSE:
IDM_STOPSERVICE: 停止服务(IOCP模型Server)
WSACleanup();
PostQuitMessage(0); //WM_DESTROY消息
IDM_STARTSERVICE: 启动服务(IOCP模型Server响应客户端请求)
InitServerSocket:函数:
1) AcceptThread线程:
Accept之后生成一个CSessionInfo对象,pNewUserInfo->sock = Accept; 客户端Socket值赋值给结构体。记录客户相关信息。
新的套接字句柄用CreateIoCompletionPort关联到完成端口,然后发出一个异步的WSASend或者WSARecv调用(pNewUserInfo->Recv();接收客户端消息),因为是异步函数,WSASend/WSARecv会马上返回,实际的发送或者接收数据的操作由WINDOWS系统去做。然后把CSessionInfo对象加入g_xSessionList中。向DBsrv服务器发送用户Session信息。打包规则‘%0socket/ip$/0’          
    在客户accept之后,总投递一个I/O(recv),然后把相应的数据发往DBSrv服务器。 
2) CreateIOCPWorkerThread函数:
调用CreateIoCompletionPort 并根据处理器数量,创建一个或多个ServerWorkerThread线程。
ServerWorkerThread线程工作原理:
循环调用GetQueuedCompletionStatus()函数来得到IO操作结果。阻塞函数。当WINDOWS系统完成WSASend或者WSArecv的操作,把结果发到完成端口。GetQueuedCompletionStatus()马上返回,并从完成端口取得刚完成的WSASend/WSARecv的结果。然后接着发出WSASend/WSARecv,并继续下一次循环阻塞在GetQueuedCompletionStatus()这里。
a). pSessionInfo为空或者dwBytesTransferred =0 ,在客户端close socket,发相应数据包(异常)到DBSrv服务器(X命令-数据包),关闭客户端套按字。
b). while ( pSessionInfo->HasCompletionPacket() ) 如果数据验证正确,就转发数据包(A命令-数据包) DBSrv服务器。
c). if (pSessionInfo->Recv() 继续投递I/O操作。
  总结:
我们不停地发出异步的WSASend/WSARecv IO操作,具体的IO处理过程由WINDOWS系统完成,WINDOWS系统完成实际的IO处理后,把结果送到完成端口上(如果有多个IO都完成了,那么就在完成端口那里排成一个队列)。我们在另外一个线程里从完成端口不断地取出IO操作结果,然后根据需要再发出WSASend/WSARecv IO操作。
IDM_STOPSERVICE: 停止服务(IOCP模型Server响应客户端请求)
   Close -> OnCommand(IDM_STOPSERVICE, 0L); ->g_fTerminated = TRUE; 线程退出。
ClearSocket(g_ssock);
ClearSocket(g_csock);
CloseHandle(g_hIOCP);
总结:SelGate(角色处理服务器),接受客户端连接,并且把用户数据包(角色处理)发送到DBSrv服务器中,由DBSrv服务器处理之后,发送数据包返回给客户端。SelGate之间是通过定时器,定时发送“心跳”数据。验证服务器存活的。客户端与服务器端的数据在传输中,是进行过加密的。
向DBSrv发送   ‘%A’+Msg+‘$0’消息: 转发客户端消息。
‘%X’+Msg+‘$0’消息: 发送用户连接消息,增加到用户列表。
‘%O’+Msg+‘$0’消息: 发送用户上线消息。
主要流程:
服务启动后,SelGate启动了AcceptThread,和ServerWorkerThread线程,AcceptThread线程接收客户端连接,并把session信息发送给DBSrv服务器,ServerWorkerThread线程从完成端口取得刚完成的WSASend/WSARecv的结果后,把客户端数据转发给DBSrv服务器。服务启动时,WSAAsyncSelect模型连接到DBSrv服务器中。一旦连接成功,就启动ThreadFuncForMsg线程,该线程从g_xMsgQueue(FD_READ事件读到的DBSrv服务器发来的数据)中取出DBSrv服务器处理过的数据。投递I/O,利用IOCP模型,发送到客户端。
ServerWorkerThread转发客户端数据-> WSAAsyncSelect的Read读DBSrv处理后返回的数据-> ThreadFuncForMsg线程,投递WSASend消息,由Windows处理(IOCP),发送数据给客户端。

传奇源码分析-服务器端(SelGate服务器分析)相关推荐

  1. 传世基本架构-服务器端(SelGate服务器分析)

    SelGate 服务器 注:客户端从 LoginSvr服务器得到SelGate服务器IP之后,连接SelGate服务器,进行角 色创建,删除,选择操作,然后发送数据到 DBSrv服务器. g_ssoc ...

  2. 关于JSP源码泄漏问题的总结分析

    JSP编程语言自从推出之日起,由于它的快速.平台无关.可扩展.面向对象等特性得到了越来越广泛的应用,越来越多的厂家开发出了各种各样的支持平台如IBM 公司的WebSphere.BEA公司的WebLog ...

  3. 直播开篇——电商直播系统源码直播场景和技术分析

    一.直播场景和技术分析 好吧,既然你们非要搞什么直播,我就开始写写直播吧,怪不得WebRTC是下一代关键技术,直播的一些业务页必须要用WebRTC来实现 1. 电商直播系统源码场景分析 秀场直播 这个 ...

  4. 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用 1...

    老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionPro ...

  5. 老李推荐:第6章1节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览 1...

    老李推荐:第6章1节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览 在上一章中我们有简要的介绍了事件源是怎么一回事,但是并没有进行详细的描述.那么往下的这几个 ...

  6. 老李推荐:第6章6节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-命令队列...

    老李推荐:第6章6节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-命令队列 事件源在获得字串命令并把它翻译成对应的MonkeyEvent事件后,会把这些事件 ...

  7. Unity3D RPG角色扮演游戏源码(上下)-----源代码分析----01-----主角人物动画

    在源代码的里面有fbx格式的模型文件,发现有2个文件,一个是骨骼动画文件,可以分割为多个动画片段,还有一个是模型文件,但是没有动画,但是可以导入分割好的动画片段到动画元素里面, 按照下面的说明,分割了 ...

  8. Unity3D RPG角色扮演游戏源码(上下)-----源代码分析----04--修改菜单窗口

    Unity3D RPG角色扮演游戏源码(上下)-----源代码分析----04--修改菜单Shop窗口 此脚本用于创建商店以销售商品 --------------------------------- ...

  9. mybatis源码之执行insert代码分析

    系列文档: mybatis源码之创建SqlSessionFactory代码分析 mybatis源码之创建SqlSessionFactory代码分析 - mapper xml解析 mybatis源码之执 ...

  10. Android 源码 Camera2 预览流程分析四

    <Android 源码 Camera2 预览流程分析二>中进行了流启动,这是调用 QCamera3Channel start() 方法实现的,对应于 HAL_PIXEL_FORMAT_YC ...

最新文章

  1. Linux学习笔记(二)文本编辑器
  2. python中*的用法
  3. 复习java基础第二天(异常处理)
  4. android 电容屏(三):驱动调试之驱动程序分析篇
  5. CDT源代码框架分析改造 线程对象的改造 添加标签 区分断点跟跟踪点
  6. 人工智能已经迫在眉睫_创意计算机已经迫在眉睫
  7. winform php 交互,WinForm开发,窗体显示和窗体传值
  8. Centos下载地址
  9. linux修改jdk版本无效,关于windows和linux系统更换JDK版本后,修改环境变量也无法生效的原因和解决办法...
  10. Android中long类型对应Java/Jni/C++中的类型
  11. Kotlin — 实现JavaEE 开发Web工程
  12. Google 网站打不开
  13. 通俗易懂的Python入门基础详细教程
  14. linux mingw32安装,在Linux上安装mingw
  15. 基于Android手机酒店客房预订系统
  16. 登录爬取拉勾网2.0 Python selenium
  17. Java问卷调查管理系统(附数据库)
  18. 虚幻引擎图文笔记:The emitter is GPU but the fixed bounds checkbox is not set警告的解决
  19. ps制作台式计算机图标,ps制作计算机图标
  20. python自动做表格_用Python做自动化的表格处理(批量智能替换) - Python趣用之法2...

热门文章

  1. 签名验证反爬,反反爬第二篇博客,Python爬虫120例
  2. 接上一篇appium安装碰到的问题ANDROID_HOME is NOT set! ,JAVA_HOME is NOT set!
  3. 有关php外文期刊,口腔外文杂志、收录数据库、参考信息汇总
  4. 如何做好企业绩效管理?
  5. noi 1.5第38题 计算多项式的导数
  6. 新品迭出,史上最强:三星电子发布会直击
  7. TI FMCW毫米波雷达基础(2)——测速原理
  8. 【毫米波雷达】LFMCW测距/测速原理
  9. 【记录】非常实用,Python编码规范的一些建议(1)
  10. SpringBoot实战笔记:记一次接口406错误的解决