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

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

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">void 
            handlePacket()<BR>{<BR>240&nbsp;&nbsp;&nbsp;&nbsp; int sock = 
            UdpSession::sock;<BR>241<BR>242&nbsp;&nbsp;&nbsp;&nbsp; for (;;) 
            {<BR>243&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fd_set 
            readfds;<BR>244&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            fd_set 
            writefds;<BR>245<BR>246&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            FD_ZERO(&amp;readfds);<BR>247&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            FD_ZERO(&amp;writefds);<BR>248<BR>249&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            FD_SET(sock, 
            &amp;readfds);<BR>250&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            int maxfd = 
            sock;<BR>251<BR>252&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if (_ops.enableS2S) 
            {<BR>253&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            int n = Server::generateFds(readfds, 
            writefds);<BR>254&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if (n &gt; 
            maxfd)<BR>255&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            maxfd = n;<BR>256&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>257<BR>258&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            timeval to;<BR>259&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            to.tv_sec = 
            1;<BR>260&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to.tv_usec 
            = 0;<BR>261<BR>262&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            int n = select(maxfd + 1, &amp;readfds, &amp;writefds, NULL, 
            &amp;to);<BR>263<BR>264&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if (n &gt; 0) 
            {<BR>265&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if (FD_ISSET(sock, 
            &amp;readfds))<BR>266&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            UdpSession::onReceive();<BR>267<BR> </P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">此函数用了winsock中的select模型,有to所以为非阻塞状态如发现有未读入的数据就调用UdpSession::onReceive()来处理,我们继续,</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">handlePacket()-&gt;UdpSession::onReceive(</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">bool 
            UdpSession::onReceive()<BR>{<BR>852&nbsp;&nbsp;&nbsp;&nbsp; char 
            buf[UDP_PACKET_SIZE];<BR>853&nbsp;&nbsp;&nbsp;&nbsp; sockaddr_in 
            addr;<BR>854&nbsp;&nbsp;&nbsp;&nbsp; socklen_t len = 
            sizeof(addr);<BR>855&nbsp;&nbsp;&nbsp;&nbsp; int n = recvfrom(sock, 
            buf, UDP_PACKET_SIZE, 0, (sockaddr *) &amp;addr, 
            &amp;len);<BR>856<BR>857&nbsp;&nbsp;&nbsp;&nbsp; if (n &lt; (int) 
            sizeof(UDP_CLI_HDR))<BR>858&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            return false;<BR>859<BR>860&nbsp;&nbsp;&nbsp;&nbsp; UdpInPacket 
            in(buf, n);<BR>861<BR> </P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">855-858从指定的sock中接收到字符后,建立一个UdpInPacket对象,它的继承关系是UdpInPacket-&gt;IcqInPacket-&gt;InPacket,构造函数如下</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">IcqInPacket(char *d, 
            int n) <BR>{<BR>&nbsp;&nbsp;&nbsp; cursor = data = (uint8 *) 
            d;<BR>&nbsp;&nbsp;&nbsp; datalen = n;<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px"> </P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">UdpInPacket::UdpInPacket(char 
            *d, int n):IcqInPacket(d, n)<BR>{<BR>&nbsp;&nbsp;&nbsp; *this 
            &gt;&gt; header.ver &gt;&gt; header.reserved;<BR>&nbsp;&nbsp;&nbsp; 
            *this &gt;&gt; header.uin &gt;&gt; header.sid &gt;&gt; 
            header.cmd;<BR>&nbsp;&nbsp;&nbsp; *this &gt;&gt; header.seq &gt;&gt; 
            header.cc;<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">UDP_CLI_HDR 
            header;</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">struct UDP_CLI_HDR 
            {<BR>&nbsp;&nbsp;&nbsp; uint16 ver;<BR>&nbsp;&nbsp;&nbsp; uint32 
            reserved;<BR>&nbsp;&nbsp;&nbsp; uint32 uin;<BR>&nbsp;&nbsp;&nbsp; 
            uint32 sid;<BR>&nbsp;&nbsp;&nbsp; uint16 cmd;<BR>&nbsp;&nbsp;&nbsp; 
            uint16 seq;<BR>&nbsp;&nbsp;&nbsp; uint16 cc; // check code<BR>};</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">InPacket 
            &amp;IcqInPacket::operator &gt;&gt;(uint8 
            &amp;b)<BR>{<BR>&nbsp;&nbsp;&nbsp; b = 0;<BR>&nbsp;&nbsp;&nbsp; if 
            (cursor &lt;= data + datalen - sizeof(b))<BR>&nbsp;&nbsp;&nbsp; b = 
            *cursor++;<BR>&nbsp;&nbsp;&nbsp; return *this;<BR>}<BR>InPacket 
            &amp;IcqInPacket::operator &gt;&gt;(uint16 
            &amp;w)<BR>{<BR>&nbsp;&nbsp;&nbsp; w = 
            ntohs(read16());<BR>&nbsp;&nbsp;&nbsp; return 
            *this;<BR>}<BR>InPacket &amp;IcqInPacket::operator &gt;&gt;(uint32 
            &amp;dw)<BR>{<BR>&nbsp;&nbsp;&nbsp; dw = 
            ntohl(read32());<BR>&nbsp;&nbsp;&nbsp; return 
            *this;<BR>}<BR>InPacket &amp;IcqInPacket::operator &gt;&gt;(ICQ_STR 
            &amp;str)<BR>{<BR>&nbsp;&nbsp;&nbsp; uint16 
            len;<BR>&nbsp;&nbsp;&nbsp; operator 
            &gt;&gt;(len);<BR><BR>&nbsp;&nbsp;&nbsp; if (len &amp;&amp; cursor 
            &lt;= data + datalen - len &amp;&amp; !cursor[len - 1]) 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str.text = (char *) 
            cursor;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str.len = len 
            - 1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cursor += 
            len;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str.text = 
            "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str.len = 
            0;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return 
            *this;<BR>}</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">uint16 
            IcqInPacket::read16()<BR>{<BR>&nbsp;&nbsp;&nbsp; uint16 w = 
            0;<BR>&nbsp;&nbsp;&nbsp; if (cursor &lt;= data + datalen - 
            sizeof(w)) {<BR>&nbsp;&nbsp;&nbsp; w = *(uint16 *) 
            cursor;<BR>&nbsp;&nbsp;&nbsp; cursor += 
            sizeof(w);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return 
            w;<BR>}<BR>uint32 IcqInPacket::read32()<BR>{<BR>&nbsp;&nbsp;&nbsp; 
            uint32 dw = 0;<BR>&nbsp;&nbsp;&nbsp; if (cursor &lt;= data + datalen 
            - sizeof(dw)) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dw = 
            *(uint32 *) cursor;<BR>&nbsp;&nbsp;&nbsp; cursor += 
            sizeof(dw);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return 
            dw;<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">上面函数的大概意思就是通过运算符重载把读入的数据从网络字节转换为主机字节后赋给UdpInPacket类的公有成员变量header;</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">让我们继续UdpSession::onReceive()</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">862&nbsp;&nbsp;&nbsp;&nbsp; 
            uint32 ip = addr.sin_addr.s_addr;<BR>863&nbsp;&nbsp;&nbsp;&nbsp; 
            uint16 port = addr.sin_port;<BR>864&nbsp;&nbsp;&nbsp;&nbsp; 
            UdpSession *s = SessionHash::get(ip, 
            port);<BR>865<BR>866&nbsp;&nbsp;&nbsp;&nbsp; if (!s) 
            {<BR>867&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint16 cmd 
            = 
            in.header.cmd;<BR>868&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            if (cmd == UDP_NEW_UIN || cmd == UDP_LOGIN) 
            {<BR>869&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            s = new UdpSession(in, ip, 
            port);<BR>870<BR>871&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // Add it to the 
            hash<BR>872&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            SessionHash::put(s, ip, 
            port);<BR>873&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            keepAliveList.add(&amp;s-&gt;listItem);<BR>874&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            } else<BR>875&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s = 
            SessionHash::get(in.header.uin);<BR>876&nbsp;&nbsp;&nbsp;&nbsp; 
            }<BR>877&nbsp;&nbsp;&nbsp;&nbsp; if 
            (s)<BR>878&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            s-&gt;onPacketReceived(in);<BR>879<BR>880&nbsp;&nbsp;&nbsp;&nbsp; 
            return true;<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">862和863把客户端的ip和port取出来,看864根据UdpSession的成员变量的队列ipportItem中找出ip、port相同的然后返回一个UdpSession</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">866-876如果队列中没有的话,并且是新建Id或是登录就新创建一个UdpSession然后用ipportItem将它链入bucket队列中,然后用listItem</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">链入keepAliveList队列。再调用onPacketReceived,这个函数是一个swith和case用来处理各种命令的跳转函数对于UPD_NEW_UIN的话就是onNewUIN(in);看onNewUIN</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">handlePacket()-&gt;UdpSession::onReceive()-&gt;UdpSession::onNewUIN</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">void 
            UdpSession::onNewUIN(UdpInPacket 
            &amp;in)<BR>{<BR>1314&nbsp;&nbsp;&nbsp; if (_ops.enableRegister) 
            {<BR>1315&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ICQ_STR 
            passwd;<BR>1316&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in 
            &gt;&gt; passwd;<BR><A 
            name=request_callback></A><BR>1317&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            DBRequest *req = new DBRequest(DBF_UPDATE | DBF_INSERT, newUserCB, 
            this, 
            in.header.seq);<BR>1318&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            WRITE_STR(req, "INSERT INTO basic_tbl (passwd, msg_id) SELECT 
            PASSWORD(");<BR>1319&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *req 
            &lt;&lt; passwd;<BR>1320&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            WRITE_STR(req, "), MAX(id) FROM 
            bcmsg_tbl");<BR>1321&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            DBManager::query(req);<BR>1322&nbsp;&nbsp;&nbsp; } else 
            {<BR>1323&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UdpOutPacket 
            *out = createPacket(UDP_NEW_UIN, 
            in.header.seq);<BR>1324&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            *out &lt;&lt; (uint32) 
            0;<BR>1325&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            sendPacket(out);<BR>1326&nbsp;&nbsp;&nbsp; 
            }<BR>1327&nbsp;&nbsp;&nbsp; isDead = 1;<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">如果现在启用了注册的话就将in中的密码赋给passwd,1317行新建一个DBRequest对象</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">DBRequest::DBRequest(uint8 
            f, DB_CALLBACK cb, RefObject *obj, uint32 
            d)<BR>{<BR>&nbsp;&nbsp;&nbsp; flags = f;<BR>&nbsp;&nbsp;&nbsp; 
            callback = cb;<BR>&nbsp;&nbsp;&nbsp; refObj = 
            obj;<BR>&nbsp;&nbsp;&nbsp; data = d;<BR>&nbsp;&nbsp;&nbsp; res = 
            NULL;<BR>&nbsp;&nbsp;&nbsp; cursor = sql;<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">注意:将sql的地址赋给了cursor.1318如下:</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">#define 
            WRITE_STR(req, str) req-&gt;writeString(str, sizeof(str) - 1)</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">void 
            writeString(const char *text, int n) </P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">{<BR>&nbsp;&nbsp;&nbsp; 
            if (cursor - sql + n &lt;= MAX_SQL) </P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(cursor, text, 
            n);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cursor += 
            n;<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">1318-1320构成的SQL语句如下:</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">INSERT INTO basic_tbl 
            (passwd, msg_id) SELECT PASSWORD("你的密码"),MAX(id) FROM bcmsg_tbl;</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">然后到1321:</P>
            <P 
            style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">handlePacket()-&gt;UdpSession::onReceive()-&gt;UdpSession::onNewUIN-&gt;DBManager::query</P>
            <P style="MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px">void 
            DBManager::query(DBRequest *req)<BR>{<BR>&nbsp;&nbsp;&nbsp; if 
            (req-&gt;callback &amp;&amp; 
            req-&gt;refObj)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            req-&gt;refObj-&gt;addRef();<BR>&nbsp;&nbsp;&nbsp; Queue &amp;q = 
            ((req-&gt;flags &amp; DBF_UPDATE) ? updateQueue : 
            queryQueue);<BR>&nbsp;&nbsp;&nbsp; 
            q.p

⌨️ 快捷键说明

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