利用SNIFFER PRO学习TCP/IP(一)

类别:VC语言 点击:0 评论:0 推荐:

 利用SNIFFER PRO学习TCP/IP(一)

2003/10/28

ydzqw 

注:Sniffer Pro应该大家都知道,不知道的到GOOGLE搜索J

最好手头有本<<TCP/IP详解卷1:协议>> 

这两天在看<<TCP/IP详解>>,总觉得有些地方理解的不够深。于是写了个小程序,再加上Sniffer,慢慢咀嚼。

程序如下:

 

---------------------Server-----------------------------

#include<iostream>

#include<winsock2.h>

#include<windows.h>

using namespace std;

 

void main()

{

       WORD wVer;

       WSADATA wsaData;

       //WSAStartup

       wVer = MAKEWORD(1, 1);

       if ( WSAStartup(wVer, &wsaData) )

       {

              cout << "WSAStaup error!";

              return;

       }

       //SOCKET init

       SOCKET sock;

       if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )

       {

              cout << "socket error!";

              return;

       }

       //bind, listen and accept

       sockaddr_in sockadr;

       sockadr.sin_family = AF_INET;

       sockadr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

       sockadr.sin_port = htons(6666);

       if ( bind(sock, (sockaddr*)&sockadr, sizeof(sockadr)) )

       {

              cout << "bind error!";

              return;

       }

       if ( listen(sock, 5) )

       {

              cout << "listen error!";

              return;

       }

       SOCKET sock_svr;

       sockaddr_in sockadr_svr;

       int iLen = sizeof(sockadr_svr);

       //accept时blocking了,如果这时要退出程序,那该如何?

       sock_svr = accept(sock, (sockaddr*)&sockadr_svr, &iLen);

       if ( sock_svr == INVALID_SOCKET )

       {

              cout << "accetp error!";

              return;

       }

 

       //select and recv

       fd_set rdfs;

       timeval tv;

       char buf[1024 * 2];

       int retval;

       int recv_err;

       tv.tv_sec = 5;

       tv.tv_usec = 0;

       for(; ;)

       {

              FD_ZERO(&rdfs);

              FD_SET(sock_svr, &rdfs);

              retval = select(0, &rdfs, NULL, NULL, &tv);

             memset(buf, 0, sizeof(buf));

              if ( retval > 0 )

              {

                     recv_err = recv(sock_svr, buf, sizeof(buf), 0);

                     if (recv_err == 0)

                     {

                            closesocket(sock_svr);

                            break;

                     }

                     else

                     {

                            cout << buf;

                     }

              }

       }

       closesocket(sock);

       WSACleanup();

}

-------------------------------------Client-------------------------------------

#include<iostream>

#include<winsock2.h>

#include<windows.h>

using namespace std;

 

void main()

{

       WORD wVer;

       WSADATA wsaData;

       //WSAStartup

       wVer = MAKEWORD(1, 1);

       if ( WSAStartup(wVer, &wsaData) )

       {

              cout << "WSAStaup error!";

              return;

       }

       //SOCKET init

       SOCKET sock;

       if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )

       {

              cout << "socket error!";

              return;

       }

       //connect and send

       sockaddr_in sockadr;

       sockadr.sin_family = AF_INET;

       //Server在本机时启用环回接口,按理说可以捕捉到数据

       //用sniffer却捕捉不到数据,这应该是Windows在底层做了相应处理

       sockadr.sin_addr.S_un.S_addr = inet_addr("192.168.1.81");

       sockadr.sin_port = htons(6666);

       if ( connect(sock, (sockaddr*)&sockadr, sizeof(sockadr)) == SOCKET_ERROR )

       {

              cout << "connect error!";

              return;

       }

 

       //分片会在哪里进行?IP层?TCP层?

       char Test[2000];

       memset(Test, 65, sizeof(Test));

       Test[sizeof(Test) - 1] = 'B';//这样才可看出是否全部传过去了

       if ( send(sock, Test, sizeof(Test), 0) == SOCKET_ERROR )

       {

              cout << "send error!";

              return;

       }

       //Sleep(1000);//等待Server的响应包再关闭

       //close and WSACleanup

       if ( closesocket(sock) )

       {

              cout << "closesocket error!";

              return;

       }

       if ( WSACleanup() )

       {

              cout << "WSACleanup error!";

              return;

       }

}

------------------------------------------------------------------------------------

 

把Client端的192.168.1.81改成运行Server端所在机器的IP地址。Client和Server不能在同一台机器(这一点我也很困惑),不然Sniffer捕捉不到数据。

Start SnifferPro(Capture->Start),接着运行Server,Client,程序一闪而过就结束了,Stop and Display SnifferPro(Capture->Stop and Display)。程序虽然一闪就结束了,没关系,我们要的东西都被Sniffer Capture了。

在面板中点击Decode,可以开始了。

注意上图,从NO.12到NO.21(当然,在你的机器执行时不见得是12-21)就是此次发送的全过程。12,13,14是建立连接的三次握手(DDoS攻击就有利用三次握手的漏洞),参见<<详解>>P176。15,16是数据传送(这里有个数据分片问题,下面会详细说明),17,19,20,21是终止连接的四次握手,18是响应包,响应15,16的数据传送。因为在我程序中send之后马上就进行closesocket,所以响应包反而到终止连接请求后面了,当然,只要在send之后Sleep(1000),就不会发生这种情况。开始我也疑惑怎么会有五次握手,在这里我没更正回来,就是为了启示大家,要小心分析。

下面开始分析数据包的结构:

本文地址:http://com.8s8s.com/it/it1380.htm