微信端口及协议分析(java、C版)(5)

<span><pre><div><span>/**</span></div><div><span> * nieyong@youku.com</span></div><div><span> * how to compile it:</span></div><div><span> * gcc pong_server.c -o pong_server /usr/local/lib/libev.a -lm </span></div><div><span> */</span></div><div><span>#include <arpa/inet.h></span></div><div><span>#include <stdlib.h></span></div><div><span>#include <stdio.h></span></div><div><span>#include <string.h></span></div><div><span>#include <fcntl.h></span></div><div><span>#include <errno.h></span></div><div><span>#include <err.h></span></div><div><span>#include <unistd.h></span></div><div> </div><div><span>#include "../include/ev.h"</span></div><div> </div><div><span>static</span> <span>int</span> <span>server_port</span> <span>=</span> <span>8080</span><span>;</span></div><div> </div><div><span>struct</span> <span>ev_loop</span> <span>*</span><span>loop</span><span>;</span></div><div><span>typedef</span> <span>struct</span> <span>{</span></div><div> <span>int</span> <span>fd</span><span>;</span></div><div> <span>ev_io</span> <span>ev_read</span><span>;</span></div><div><span>}</span> <span>client_t</span><span>;</span></div><div> </div><div><span>ev_io</span> <span>ev_accept</span><span>;</span></div><div> </div><div><span>static</span> <span>void</span> <span>free_res</span><span>(</span><span>struct</span> <span>ev_loop</span> <span>*</span><span>loop</span><span>,</span> <span>ev_io</span> <span>*</span><span>ws</span><span>);</span></div><div> </div><div><span>int</span> <span>setnonblock</span><span>(</span><span>int</span> <span>fd</span><span>)</span> <span>{</span></div><div> <span>int</span> <span>flags</span> <span>=</span> <span>fcntl</span><span>(</span><span>fd</span><span>,</span> <span>F_GETFL</span><span>);</span></div><div> <span>if</span> <span>(</span><span>flags</span> <span><</span> <span>0</span><span>)</span></div><div> <span>return</span> <span>flags</span><span>;</span></div><div> </div><div> <span>flags</span> <span>|=</span> <span>O_NONBLOCK</span><span>;</span></div><div> <span>if</span> <span>(</span><span>fcntl</span><span>(</span><span>fd</span><span>,</span> <span>F_SETFL</span><span>,</span> <span>flags</span><span>)</span> <span><</span> <span>0</span><span>)</span></div><div> <span>return</span> <span>-</span><span>1</span><span>;</span></div><div> </div><div> <span>return</span> <span>0</span><span>;</span></div><div><span>}</span></div><div> </div><div><span>static</span> <span>void</span> <span>read_cb</span><span>(</span><span>struct</span> <span>ev_loop</span> <span>*</span><span>loop</span><span>,</span> <span>ev_io</span> <span>*</span><span>w</span><span>,</span> <span>int</span> <span>revents</span><span>)</span> <span>{</span></div><div> <span>client_t</span> <span>*</span><span>client</span> <span>=</span> <span>w</span><span>-></span><span>data</span><span>;</span></div><div> <span>int</span> <span>r</span> <span>=</span> <span>0</span><span>;</span></div><div> <span>char</span> <span>rbuff</span><span>[</span><span>1024</span><span>];</span></div><div> <span>if</span> <span>(</span><span>revents</span> <span>&</span> <span>EV_READ</span><span>)</span> <span>{</span></div><div> <span>r</span> <span>=</span> <span>read</span><span>(</span><span>client</span><span>-></span><span>fd</span><span>,</span> <span>&</span><span>rbuff</span><span>,</span> <span>1024</span><span>);</span></div><div> <span>}</span></div><div> </div><div> <span>if</span> <span>(</span><span>EV_ERROR</span> <span>&</span> <span>revents</span><span>)</span> <span>{</span></div><div> <span>fprintf</span><span>(</span><span>stderr</span><span>,</span> <span>"error event in read</span><span>\n</span><span>"</span><span>);</span></div><div> <span>free_res</span><span>(</span><span>loop</span><span>,</span> <span>w</span><span>);</span></div><div> <span>return</span> <span>;</span></div><div> <span>}</span></div><div> </div><div> <span>if</span> <span>(</span><span>r</span> <span><</span> <span>0</span><span>)</span> <span>{</span></div><div> <span>fprintf</span><span>(</span><span>stderr</span><span>,</span> <span>"read error</span><span>\n</span><span>"</span><span>);</span></div><div> <span>ev_io_stop</span><span>(</span><span>EV_A_</span> <span>w</span><span>);</span></div><div> <span>free_res</span><span>(</span><span>loop</span><span>,</span> <span>w</span><span>);</span></div><div> <span>return</span><span>;</span></div><div> <span>}</span></div><div> </div><div> <span>if</span> <span>(</span><span>r</span> <span>==</span> <span>0</span><span>)</span> <span>{</span></div><div> <span>fprintf</span><span>(</span><span>stderr</span><span>,</span> <span>"client disconnected.</span><span>\n</span><span>"</span><span>);</span></div><div> <span>ev_io_stop</span><span>(</span><span>EV_A_</span> <span>w</span><span>);</span></div><div> <span>free_res</span><span>(</span><span>loop</span><span>,</span> <span>w</span><span>);</span></div><div> <span>return</span><span>;</span></div><div> <span>}</span></div><div> </div><div> <span>send</span><span>(</span><span>client</span><span>-></span><span>fd</span><span>,</span> <span>rbuff</span><span>,</span> <span>r</span><span>,</span> <span>0</span><span>);</span></div><div><span>}</span></div><div> </div><div><span>static</span> <span>void</span> <span>accept_cb</span><span>(</span><span>struct</span> <span>ev_loop</span> <span>*</span><span>loop</span><span>,</span> <span>ev_io</span> <span>*</span><span>w</span><span>,</span> <span>int</span> <span>revents</span><span>)</span> <span>{</span></div><div> <span>struct</span> <span>sockaddr_in</span> <span>client_addr</span><span>;</span></div><div> <span>socklen_t</span> <span>client_len</span> <span>=</span> <span>sizeof</span><span>(</span><span>client_addr</span><span>);</span></div><div> <span>int</span> <span>client_fd</span> <span>=</span> <span>accept</span><span>(</span><span>w</span><span>-></span><span>fd</span><span>,</span> <span>(</span><span>struct</span> <span>sockaddr</span> <span>*</span><span>)</span> <span>&</span><span>client_addr</span><span>,</span> <span>&</span><span>client_len</span><span>);</span></div><div> <span>if</span> <span>(</span><span>client_fd</span> <span>==</span> <span>-</span><span>1</span><span>)</span> <span>{</span></div><div> <span>fprintf</span><span>(</span><span>stderr</span><span>,</span> <span>"the client_fd is NULL !</span><span>\n</span><span>"</span><span>);</span></div><div> <span>return</span><span>;</span></div><div> <span>}</span></div><div> </div><div> <span>client_t</span> <span>*</span><span>client</span> <span>=</span> <span>malloc</span><span>(</span><span>sizeof</span><span>(</span><span>client_t</span><span>));</span></div><div> <span>client</span><span>-></span><span>fd</span> <span>=</span> <span>client_fd</span><span>;</span></div><div> <span>if</span> <span>(</span><span>setnonblock</span><span>(</span><span>client</span><span>-></span><span>fd</span><span>)</span> <span><</span> <span>0</span><span>)</span></div><div> <span>err</span><span>(</span><span>1</span><span>,</span> <span>"failed to set client socket to non-blocking"</span><span>);</span></div><div> </div><div> <span>client</span><span>-></span><span>ev_read</span><span>.</span><span>data</span> <span>=</span> <span>client</span><span>;</span></div><div> </div><div> <span>ev_io_init</span><span>(</span><span>&</span><span>client</span><span>-></span><span>ev_read</span><span>,</span> <span>read_cb</span><span>,</span> <span>client</span><span>-></span><span>fd</span><span>,</span> <span>EV_READ</span><span>);</span></div><div> <span>ev_io_start</span><span>(</span><span>loop</span><span>,</span> <span>&</span><span>client</span><span>-></span><span>ev_read</span><span>);</span></div><div><span>}</span></div><div> </div><div><span>int</span> <span>main</span><span>(</span><span>int</span> <span>argc</span><span>,</span> <span>char</span> <span>const</span> <span>*</span><span>argv</span><span>[])</span> <span>{</span></div><div> <span>int</span> <span>ch</span><span>;</span></div><div> <span>while</span> <span>((</span><span>ch</span> <span>=</span> <span>getopt</span><span>(</span><span>argc</span><span>,</span> <span>argv</span><span>,</span> <span>"p:"</span><span>))</span> <span>!=</span> <span>-</span><span>1</span><span>)</span> <span>{</span></div><div> <span>switch</span> <span>(</span><span>ch</span><span>)</span> <span>{</span></div><div> <span>case</span> <span>'p'</span><span>:</span></div><div> <span>server_port</span> <span>=</span> <span>atoi</span><span>(</span><span>optarg</span><span>);</span></div><div> <span>break</span><span>;</span></div><div> <span>}</span></div><div> <span>}</span></div><div> </div><div> <span>loop</span> <span>=</span> <span>ev_default_loop</span><span>(</span><span>0</span><span>);</span></div><div> <span>struct</span> <span>sockaddr_in</span> <span>listen_addr</span><span>;</span></div><div> <span>int</span> <span>reuseaddr_on</span> <span>=</span> <span>1</span><span>;</span></div><div> <span>int</span> <span>listen_fd</span> <span>=</span> <span>socket</span><span>(</span><span>AF_INET</span><span>,</span> <span>SOCK_STREAM</span><span>,</span> <span>0</span><span>);</span></div><div> <span>if</span> <span>(</span><span>listen_fd</span> <span><</span> <span>0</span><span>)</span></div><div> <span>err</span><span>(</span><span>1</span><span>,</span> <span>"listen failed"</span><span>);</span></div><div> <span>if</span> <span>(</span><span>setsockopt</span><span>(</span><span>listen_fd</span><span>,</span> <span>SOL_SOCKET</span><span>,</span> <span>SO_REUSEADDR</span><span>,</span> <span>&</span><span>reuseaddr_on</span><span>,</span> <span>sizeof</span><span>(</span><span>reuseaddr_on</span><span>))</span> <span>==</span> <span>-</span><span>1</span><span>)</span></div><div> <span>err</span><span>(</span><span>1</span><span>,</span> <span>"setsockopt failed"</span><span>);</span></div><div> </div><div> <span>memset</span><span>(</span><span>&</span><span>listen_addr</span><span>,</span> <span>0</span><span>,</span> <span>sizeof</span><span>(</span><span>listen_addr</span><span>));</span></div><div> <span>listen_addr</span><span>.</span><span>sin_family</span> <span>=</span> <span>AF_INET</span><span>;</span></div><div> <span>listen_addr</span><span>.</span><span>sin_addr</span><span>.</span><span>s_addr</span> <span>=</span> <span>INADDR_ANY</span><span>;</span></div><div> <span>listen_addr</span><span>.</span><span>sin_port</span> <span>=</span> <span>htons</span><span>(</span><span>server_port</span><span>);</span></div><div> </div><div> <span>if</span> <span>(</span><span>bind</span><span>(</span><span>listen_fd</span><span>,</span> <span>(</span><span>struct</span> <span>sockaddr</span> <span>*</span><span>)</span> <span>&</span><span>listen_addr</span><span>,</span> <span>sizeof</span><span>(</span><span>listen_addr</span><span>))</span> <span><</span> <span>0</span><span>)</span></div><div> <span>err</span><span>(</span><span>1</span><span>,</span> <span>"bind failed"</span><span>);</span></div><div> <span>if</span> <span>(</span><span>listen</span><span>(</span><span>listen_fd</span><span>,</span> <span>5</span><span>)</span> <span><</span> <span>0</span><span>)</span></div><div> <span>err</span><span>(</span><span>1</span><span>,</span> <span>"listen failed"</span><span>);</span></div><div> <span>if</span> <span>(</span><span>setnonblock</span><span>(</span><span>listen_fd</span><span>)</span> <span><</span> <span>0</span><span>)</span></div><div> <span>err</span><span>(</span><span>1</span><span>,</span> <span>"failed to set server socket to non-blocking"</span><span>);</span></div><div> </div><div> <span>ev_io_init</span><span>(</span><span>&</span><span>ev_accept</span><span>,</span> <span>accept_cb</span><span>,</span> <span>listen_fd</span><span>,</span> <span>EV_READ</span><span>);</span></div><div> <span>ev_io_start</span><span>(</span><span>loop</span><span>,</span> <span>&</span><span>ev_accept</span><span>);</span></div><div> <span>ev_loop</span><span>(</span><span>loop</span><span>,</span> <span>0</span><span>);</span></div><div> </div><div> <span>return</span> <span>0</span><span>;</span></div><div><span>}</span></div><div> </div><div><span>static</span> <span>void</span> <span>free_res</span><span>(</span><span>struct</span> <span>ev_loop</span> <span>*</span><span>loop</span><span>,</span> <span>ev_io</span> <span>*</span><span>w</span><span>)</span> <span>{</span></div><div> <span>client_t</span> <span>*</span><span>client</span> <span>=</span> <span>w</span><span>-></span><span>data</span><span>;</span></div><div> <span>if</span> <span>(</span><span>client</span> <span>==</span> <span>NULL</span><span>)</span> <span>{</span></div><div> <span>fprintf</span><span>(</span><span>stderr</span><span>,</span> <span>"the client is NULL !!!!!!"</span><span>);</span></div><div> <span>return</span><span>;</span></div><div> <span>}</span></div><div> </div><div> <span>ev_io_stop</span><span>(</span><span>loop</span><span>,</span> <span>&</span><span>client</span><span>-></span><span>ev_read</span><span>);</span></div><div> <span>close</span><span>(</span><span>client</span><span>-></span><span>fd</span><span>);</span></div><div> <span>free</span><span>(</span><span>client</span><span>);</span></div><div><span>}</span></div></span>

这里有一个现场图:

2014-03-03_14h53_19

可以尝试稍微改变输出内容,去除换行符“\n”,把端口换成9000,试试看,就会发现Wireshark输出不同的结果来。

2.3 结论是什么呢?

若使用原始TCP进行双向通信,则需要满足以下条件,可以被类似于Wireshark协议拦截器误认为是HTTP长连接:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzzpfz.html