⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csdn_文档中心_myicq情景分析.htm

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            1;<BR>223&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            *(uint32 *) p = 
            destIP;<BR>224&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            p += 
            sizeof(uint32);<BR>225&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            } else 
            {<BR>226&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // Domain 
            name<BR>227&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            *p++ = 
            3;<BR>228&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            string &amp;domain = 
            icqLink-&gt;myInfo.qid.domain;<BR>229&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            uint8 len = 
            domain.length();<BR>230&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            *p++ = 
            len;<BR>231&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            memcpy(p, domain.c_str(), 
            len);<BR>232&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            p += 
            len;<BR>233&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>234&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            *(uint16 *) p = 
            htons(options.port);<BR>235&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            p += 
            sizeof(uint16);<BR>236&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            break;<BR>237&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>238&nbsp;&nbsp; }<BR>239&nbsp;&nbsp; memcpy(p, 
            out-&gt;getData(), n);<BR>240&nbsp;&nbsp; p += n;<BR>241&nbsp;&nbsp; 
            send(s, buf, p - buf, 0);<BR>&nbsp; }</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px"><A name=main></A></P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">此函数功能主要是通过send()发送数据(updsesson::data)给服务器,本情景也就是发用户填写的信息.</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">从此将进入服务器代码直到服务器返回为此。看服务器代码:</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">此函数在main.cpp中</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">int main(int argc, 
            char *argv[])<BR>{<BR>66&nbsp;&nbsp;&nbsp;&nbsp; WSADATA 
            wsaData;<BR>67&nbsp;&nbsp;&nbsp;&nbsp; WORD version = MAKEWORD(2, 
            2);<BR>68&nbsp;&nbsp;&nbsp;&nbsp; if (WSAStartup(version, 
            &amp;wsaData) != 
            0)<BR>69&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
            1;<BR>70<BR>71&nbsp;&nbsp;&nbsp;&nbsp; initArgs(argc, 
            argv);<BR>72<BR>73 #ifndef _DEBUG<BR>74&nbsp;&nbsp;&nbsp;&nbsp; if 
            (!startService())<BR>75 #endif<BR>76&nbsp;&nbsp;&nbsp;&nbsp; 
            {<BR>77&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // We are not in service 
            mode<BR>78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
            (myicqStart()) 
            {<BR>79&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            handlePacket();<BR>80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            myicqDestroy();<BR>81&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>82&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>83<BR>84&nbsp;&nbsp;&nbsp;&nbsp; 
            WSACleanup();<BR>85&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">66行到70行初始化winsock,版本为2.2。71行的initArgs(argc,argv)处理参数主要是如果是windows的话将myicq加入到服务中,以后系统启动时自动运行。到78行我们看myicqStart的代码(main.cpp),main()-&gt;myicqStart()</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">bool 
            myicqStart()<BR>{<BR>45&nbsp;&nbsp;&nbsp;&nbsp; if 
            (!myicqInit())<BR>46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            return 
            false;<BR>进入myicqInit(myicq.cpp)中,main()-&gt;myicqStart()-&gt;myicqInit()</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">bool 
            myicqInit()<BR>{<BR>187&nbsp;&nbsp;&nbsp;&nbsp; 
            srand(time(&amp;curTime));<BR>188<BR>189&nbsp;&nbsp;&nbsp;&nbsp; 
            parseProfile(CONFIG_FILE, 
            parseConfig);<BR>190<BR>191&nbsp;&nbsp;&nbsp;&nbsp; 
            Log::open(_ops.logFile.c_str(), 
            _ops.logLevel);<BR>192<BR>193&nbsp;&nbsp;&nbsp;&nbsp; 
            loadPlugins();<BR>194<BR>195&nbsp;&nbsp;&nbsp;&nbsp; // Initialize 
            database subsystem<BR>196&nbsp;&nbsp;&nbsp;&nbsp; if 
            (!DBManager::init(_ops.dbInfo)) 
            {<BR>197&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG(1) 
            ("Cannot connect to mysql 
            master\n");<BR>198&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            return false;<BR>199&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>200&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; NR_DB_QUERY; 
            ++i) {<BR>201&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
            (!dbQuery[i].create(_ops.dbInfo)) 
            {<BR>202&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            LOG(1) ("Cannot connect to mysql 
            slave\n");<BR>203&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            return false;<BR>204&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>205&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>206<BR>207&nbsp;&nbsp;&nbsp;&nbsp; if 
            (!UdpSession::init())<BR>208&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            return false;<BR>209<BR>210&nbsp;&nbsp;&nbsp;&nbsp; if 
            (_ops.enableS2S) 
            {<BR>211&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
            (!Server::init())<BR>212&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            return 
            false;<BR>213<BR>214&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            LOG(1) ("domain name is %s\n", 
            _ops.domain.c_str());<BR>215&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>216<BR>217&nbsp;&nbsp;&nbsp;&nbsp; LOG(1) ("myicqd is now 
            started.\n");<BR>218&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">189行的parseProfile是函数主要功能是从CONFIG_FILE指定的文件中取各各节的内容存入OPTIONS 
            _ops这个全局结构中.</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">struct OPTIONS 
            {<BR>&nbsp;&nbsp;&nbsp; // network<BR>&nbsp;&nbsp;&nbsp; uint32 
            myicqIP;<BR>&nbsp;&nbsp;&nbsp; uint16 
            myicqPort;<BR>&nbsp;&nbsp;&nbsp; // log<BR>&nbsp;&nbsp;&nbsp; int 
            logLevel;<BR>&nbsp;&nbsp;&nbsp; string 
            logFile;<BR>&nbsp;&nbsp;&nbsp; // mysql<BR>&nbsp;&nbsp;&nbsp; 
            DB_INFO dbInfo;<BR>&nbsp;&nbsp;&nbsp; int 
            enableRegister;<BR>&nbsp;&nbsp;&nbsp; int 
            enableS2S;<BR>&nbsp;&nbsp;&nbsp; // server<BR>&nbsp;&nbsp;&nbsp; 
            string domain;<BR>&nbsp;&nbsp;&nbsp; string 
            desc;<BR>&nbsp;&nbsp;&nbsp; // plugins<BR>&nbsp;&nbsp;&nbsp; string 
            pluginDir;<BR>};</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">191打开日志文件,193加载插件模块。196-199通过调用mysql_init(mysql提供)并用mysql_real_connect连接;初始化mysql赋给mysqlWrite,参数是_ops.dbInfo.,200-205也是调用mysql_init来初始化mysql_real_connect连接;static 
            DBManager dbQuery[NR_DB_QUERY];结构中的MYICQ* 
            mysqlRead;,207-208初始化UPD服务UpdSession::init()(updsession.cpp)</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">main()-&gt;myicqStart()-&gt;myicqInit()-&gt;UpdSession::init()</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">bool 
            UdpSession::init()<BR>{<BR>696&nbsp;&nbsp;&nbsp;&nbsp; sockaddr_in 
            addr;<BR>697<BR>698&nbsp;&nbsp;&nbsp;&nbsp; qidAdmin.uin = 
            ADMIN_UIN;<BR>699&nbsp;&nbsp;&nbsp;&nbsp; qidAdmin.domain = 
            emptyStr;<BR>700<BR>701&nbsp;&nbsp;&nbsp;&nbsp; sock = 
            socket(AF_INET, SOCK_DGRAM, 0);<BR>702&nbsp;&nbsp;&nbsp;&nbsp; if 
            (sock &lt; 0) 
            {<BR>703&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG(1) 
            ("socket() 
            failed\n");<BR>704&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            goto failed;<BR>705&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>706<BR>707&nbsp;&nbsp;&nbsp;&nbsp; memset(&amp;addr, 0, 
            sizeof(addr));<BR>708&nbsp;&nbsp;&nbsp;&nbsp; addr.sin_family = 
            AF_INET;<BR>709&nbsp;&nbsp;&nbsp;&nbsp; addr.sin_addr.s_addr = 
            _ops.myicqIP;<BR>710&nbsp;&nbsp;&nbsp;&nbsp; addr.sin_port = 
            _ops.myicqPort;<BR>711&nbsp;&nbsp;&nbsp;&nbsp; if (bind(sock, 
            (sockaddr *) &amp;addr, sizeof(addr)) &lt; 0) 
            {<BR>712&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOG(1) 
            ("bind(): Can not bind on 
            %s:%d\n",<BR>713&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            inet_ntoa(addr.sin_addr), 
            ntohs(_ops.myicqPort));<BR>714&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            goto failed;<BR>715&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>716<BR>717&nbsp;&nbsp;&nbsp;&nbsp; 
            desinit(0);<BR>718&nbsp;&nbsp;&nbsp;&nbsp; return 
            true;<BR>719<BR>720&nbsp;&nbsp;&nbsp;&nbsp; 
            failed:<BR>721&nbsp;&nbsp;&nbsp;&nbsp; if (sock &gt;= 
            0)<BR>722&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            close(sock);<BR>723&nbsp;&nbsp;&nbsp;&nbsp; return false;<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">此函数就是对socket的一些初始化工作socket初始化流程 
            socket() ---&nbsp; bind() --- 
            listen()注:此函数中还没有listen()用的是(无连接的)UDP协议</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">Server::init()主要是初始化(面向连接的)TCP协议,然后返回到myicqStart中看代码:</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px"><A 
            name=Thread></A></P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">48&nbsp;&nbsp;&nbsp;&nbsp; 
            DWORD id;<BR>49&nbsp;&nbsp;&nbsp;&nbsp; int 
            i;<BR>50<BR>51&nbsp;&nbsp;&nbsp;&nbsp; // Creating 
            threads...<BR>52&nbsp;&nbsp;&nbsp;&nbsp; CreateThread(NULL, 0, 
            pulseThread, NULL, 0, &amp;id);<BR>53<BR>54&nbsp;&nbsp;&nbsp;&nbsp; 
            // DNS<BR>55&nbsp;&nbsp;&nbsp;&nbsp; CreateThread(NULL, 0, 
            dnsThread, NULL, 0, &amp;id);<BR>56<BR>57&nbsp;&nbsp;&nbsp;&nbsp; 
            CreateThread(NULL, 0, dbUpdateThread, NULL, 0, 
            &amp;id);<BR>58&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; 
            NR_DB_QUERY; 
            ++i)<BR>59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            CreateThread(NULL, 0, dbQueryThread, (LPVOID) i, 0, 
            &amp;id);<BR>60<BR>61&nbsp;&nbsp;&nbsp;&nbsp; return 
            true;<BR>}<BR>建立了几个线程回调函数分别是pulseThread, dnsThread, dbUpdateThread, 
            dbQueryThread;</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">static DWORD WINAPI 
            pulseThread(LPVOID)<BR>{<BR>&nbsp;&nbsp;&nbsp; 
            pulse();<BR>&nbsp;&nbsp;&nbsp; return 0;<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">void 
            pulse()<BR>{<BR>&nbsp;&nbsp;&nbsp; for (;;) 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time((time_t *) 
            &amp;curTime);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            sleep(1);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">static DWORD WINAPI 
            dnsThread(LPVOID)<BR>{&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 
            handleDNS();<BR>&nbsp;&nbsp;&nbsp; return 0;<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">void 
            handleDNS()<BR>{<BR>&nbsp;&nbsp;&nbsp; 
            DNSManager::process();<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">static DWORD WINAPI 
            dbUpdateThread(LPVOID)<BR>{<BR>&nbsp;&nbsp;&nbsp; 
            handleDBUpdate();<BR>&nbsp;&nbsp;&nbsp; return 0;<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">void 
            handleDBUpdate()<BR>{<BR>&nbsp;&nbsp;&nbsp; 
            DBManager::processUpdate();<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">先继续向下看吧!回到main中还剩以下几行</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">79&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            handlePacket();<BR>80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            myicqDestroy();<BR>81&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>82&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>83<BR>84&nbsp;&nbsp;&nbsp;&nbsp; 
            WSACleanup();<BR>85&nbsp;&nbsp;&nbsp;&nbsp; return 0;</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">最重要的是handlePacket(),看代码:</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -