TCP回射服务器/客户端分析

时间:2014-10-26 06:45:26   收藏:0   阅读:867

本文将对一个简单的TCP回射服务器和客户端进行抓包,从而分析一次成功而理想TCP会话的基本流程,多次不成功或与预期不一致的抓包结果将在下篇博文进行分析

 

本文程序编译环境为:

Linux version 3.16.4-1-ARCH

gcc version 4.9.1 20140903 (prerelease)

Glibc 2.18

服务器代码如下:

 1 #include <unistd.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 
 7 #include <stdio.h>
 8 #include <stdlib.h>
 9 #include <string.h>
10 
11 #define ERR_EXIT(exp) 12     do13     {14         perror(exp);15         exit(EXIT_FAILURE);16     }while(0)
17 
18 #define BUFSIZE 1024
19 
20 int main(int argc, char *argv[])
21 {
22     if(argc != 2)
23         ERR_EXIT("Usage: a.out <port>");
24 
25     int server_sock;
26     int client_sock;
27     struct sockaddr_in server_addr;
28     struct sockaddr_in client_addr;
29     socklen_t server_len;
30     socklen_t client_len;
31 
32     server_sock = socket(PF_INET, SOCK_STREAM, 0);
33     if(server_sock == -1)
34         ERR_EXIT("socket");
35 
36     memset(&server_addr, 0, sizeof(server_addr));
37     server_addr.sin_family = AF_INET;
38     server_addr.sin_addr.s_addr = INADDR_ANY;
39     server_addr.sin_port = htons(atoi(argv[1]));
40     server_len = sizeof(server_addr);
41     client_len = sizeof(client_addr);
42 
43     if(bind(server_sock, (struct sockaddr*)&server_addr, server_len) == -1)
44         ERR_EXIT("bind");
45 
46     if(listen(server_sock, 5) == -1)
47         ERR_EXIT("listen");
48 
49     client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_len);
50     if(client_sock == -1)
51         ERR_EXIT("accept");
52     char buffer[BUFSIZE];
53     read(client_sock, buffer, BUFSIZE);
54     write(client_sock, buffer, strlen(buffer));
55 
56     sleep(3);
57     close(client_sock);
58     close(server_sock);
59     return 0;
60 }

 

客户端代码如下:

 1 #include <unistd.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 
 7 #include <stdio.h>
 8 #include <stdlib.h>
 9 #include <string.h>
10 
11 #define ERR_EXIT(exp) 12     do13     {14         perror(exp);15         exit(EXIT_FAILURE);16     }while(0)
17 
18 #define BUFSIZE 1024
19 
20 int main(int argc, char *argv[])
21 {
22     if(argc != 3)
23         ERR_EXIT("Usage: a.out <server_ip> <port>");
24 
25     int server_sock;
26     struct sockaddr_in server_addr;
27     socklen_t server_len;
28 
29     server_sock = socket(PF_INET, SOCK_STREAM, 0);
30     if(server_sock == -1)
31         ERR_EXIT("socket");
32 
33     server_addr.sin_family = AF_INET;
34     server_addr.sin_addr.s_addr = inet_addr(argv[1]);
35     server_addr.sin_port = htons(atoi(argv[2]));
36     server_len = sizeof(server_addr);
37 
38     if(connect(server_sock, (struct sockaddr*)&server_addr, server_len) == -1)
39         ERR_EXIT("connect");
40 
41     char buffer[BUFSIZE] = "Hello World!";
42     write(server_sock, buffer, strlen(buffer));
43     memset(buffer, 0, BUFSIZE);
44     read(server_sock, buffer, BUFSIZE);
45     printf("%s\n", buffer);
46 
47     sleep(1);
48     close(server_sock);
49     return 0;
50 }

 

首先展示抓包结果,这是一个完全符合书本理论的理想状况,下篇博客将会通过调试器等手段制造非理想状况,进而分析其行为,因此不对TCP包结构进行讨论,TCP包的WIN字段用于滑动窗口的控制,本文暂不涉及

 

bubuko.com,布布扣

首先:一次TCP会话的基本流程应该分为以下三步

  1. 与对方套接字建立连接
  2. 与对方套接字进行数据交换
  3. 断开与对方套接字的连接

下面即对抓包结果进行分析,从而分析出这三个步骤中实际发生了什么,需要说明的是,抓包得到的No序号和TCP包中seq和ack的序号不是一个东西,由于我使用SSH连接了测试机进行控制,因此抓包软件连同SSH的数据包一并抓取,造成与我们测试内容相关的数据包序号不连续,不过这并不影响我们的分析和理解

22,24,25号数据包即TCP会话基本流程的第一步:与对方套接字建立连接,这个过程一共进行了三次数据包的传递,也就是俗称的三次握手

26,27,28,29四个数据包展示了客户端服务端进行一次数据交换的过程,两个来回,并根据实际的业务逻辑而变化,这就是TCP会话中的第二步:与对方套接字进行数据交换

32,34,36,37号包实现了一次TCP会话中的第三步:断开与对方套接字的连接,这个过程经历了四次数据包的传递,也就是俗称的四次挥手,至此,一次TCP会话成功完成,下篇博文将会讨论一次TCP会话中的状态转移,并分析一些和本文不同的抓包结果

 

原文:http://www.cnblogs.com/current/p/4051313.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!