2023年12月6日发(作者:)

北京工业大学

计算机学院

实验报告

课程名称 TCPIP协议分析

学 号

姓 名

网络协议分析实验

一、实验目的

通过使用协议分析软件,对通信系统的通信过程进行监控、分析,以了解通信协议的工作过程。

二、实验内容

利用协议分析软件(如:Wireshark)跟踪局域网报文(如条件允许也可跟踪多种局域网协议报文),实验内容如下:

将安装协议分析软件的PC接入以太网中,跟踪PC之间的报文,并存入文件以备重新查。

设置过滤器过滤网络报文以检测特定数据流。

利用协议分析软件的统计工具显示网络报文的各种统计信息。

三、实验步骤

1、在PC中安装协议分析软件(如:Wireshark)。具体安装过程详见附录:Wireshark用户指南。

2、启动Wireshark协议分析软件,选择抓包菜单项启动实时监视器,开始实时跟踪显示网络数据报文。可根据系统提示修改显示方式,详见附录:Wireshark用户指南。

3、调出跟踪存储的历史报文,选择有代表性的ETHERNET,IEEE802.3,IP,ICMP,TCP,UDP报文,对照有关协议逐个分析报文各字段的含义及内容。

EHERNET报文格式

DSTADDR

6字节

IEEE802.3报文格式

SRCADDR TYPE

6字节 2字节

最大长度1518字节

INFO

DSTADDR

6字节

SRCADDR

6字节

LEN DSAP SSAP

2字1字1字节 节 节

最大长度1518字节

CONTROL

1/2字节

INFO

信息

IP报文格式 VERSION IHL TOS TOTAL LENGTN

IDENTIFICATION FLAGS FRAGMENT OFFSET

TTL PROTOWT HEADER CHECLCSUM

SOWRCE ADDRESS

DRSTINWTION ADDRESS

OPTIONS PADDING

INFO

4、设置过滤器属性,如目的地址,源地址,协议类型等。如过滤不需要的网络报文,过滤器允许设置第二层,第三层或第四层的协议字段。

过滤器有两种工作方式:

1)捕获前过滤:协议分析软件用过滤器匹配网络上的数据报文,仅当匹配通过时才捕获报文。

2)捕获后过滤:协议分析软件捕获所有报文,但仅显示匹配符合过滤条件的报文。

选择统计菜单项可以显示网络中各种流量的统计信息,如:关于字节数,广播中报文数,出错数等。 UDP客户/服务器实验

一、实验目的

本实验目的是使用因特网提供的UDP传输协议,实现一个简单的UDP客户/服务器程序,以了解传输层所提供的UDP服务的特点,应用层和传输层之间的软件接口风格,熟悉socket机制和UDP客户端/服务器方式程序的结构。

二、实验内容

本实验为UDP客户/服务器实验。实验内容:UDP echo客户/服务器程序的设计与实现。UDP echo客户/服务器程序完成以下功能:

客户从标准输入读一行文本,写到服务器上;服务器从网络输入读取此行,并回射(echo)给客户;客户读此回射行,并将其写到标准输出。

三、实验步骤

1、 总体设计

客户程序从标准输入读一行文本,写到服务器程序上;服务器程序从网络输入读取此行,并回射给客户程序;客户程序读此回射行,并将其写到标准输出。

2、 详细设计

stdinstdoutfgetsUDP客户fputssendtorecvfromrecvfromUDP服务器sendto

UDP客户-服务器程序所用套接口函数1)服务器main函数

创建UDP套接口,捆绑服务器的众所周知端口调用函数dg_echo来进行服务器的处理

2)服务器str_echo函数 recvfrom读下一格到达服务器端口的数据报用sendto将它发回

3)客户main函数

用服务器的IP地址和端口号装填一个IPv4 的套接口地址结构创建一个UDP套接口,调用dg_cli函数

4)客户str_echo函数

fgets读一行文本fgets遇到文件结束或错误YNsendto将此行发送到服务器recvfrom从服务器读回射,fputs将回射行写到标准输出

Serv

#include

#include

#include

#include

#include

#define MAXLINE 4096

#define LISTENQ 1024 /* 2nd argument to listen() */

#define SERV_PORT 9877

#define SA struct sockaddr

static int sockfd;

void dg_echo(int, SA *, socklen_t);

int

main(int argc, char ** argv)

{

}

void

dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)

{

int n;

socklen_t len;

char mesg[MAXLINE];

for ( ; ; ) {

len = clilen;

n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);

struct sockaddr_in servaddr, cliaddr;

if((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0) {

printf("socket error.n");

exit(1);

}

bzero(&servaddr, sizeof(servaddr));

_family = AF_INET;

_addr.s_addr = htonl(INADDR_ANY);

_port = htons(SERV_PORT);

bind(sockfd, (SA *)&servaddr, sizeof(servaddr));

dg_echo(sockfd, (SA *)&cliaddr, sizeof(cliaddr));

sendto(sockfd, mesg, n, 0, pcliaddr, len);

}

}

Cli

#include

#include

#include

#include

#include

#define MAXLINE 4096

#define LISTENQ 1024 /* 2nd argument to listen() */

#define SERV_PORT 9877

#define SA struct sockaddr

void dg_cli(FILE *, int, const SA *, socklen_t);

main(int argc, char **argv)

{

}

int sockfd;

struct sockaddr_in servaddr;

if (argc != 2) {

printf("usage:udpcli01sigio n");

}

exit(1);

bzero(&servaddr, sizeof(servaddr));

_family = AF_INET;

_port = htons(SERV_PORT);

inet_pton(AF_INET, argv[1], &_addr);

if((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0) {

printf("socket error.n");

}

dg_cli(stdin, sockfd, (SA *)&servaddr, sizeof(servaddr));

exit(0);

exit(1); void

dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

{

int n;

char sendline[MAXLINE], recvline[MAXLINE + 1];

}

while (fgets(sendline, MAXLINE,fp) != NULL) {

}

sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);

n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);

recvline[n] = 0; /* null terminate */

fputs(recvline, stdout);

TCP客户/服务器实验

四、实验目的

本实验目的是使用因特网提供的TCP传输协议,实现一个简单的TCP客户/服务器程序,以了解传输层所提供的TCP服务的特点,应用层和传输层之间的软件接口风格,熟悉socket机制和TCP客户端/服务器方式程序的结构。

五、实验内容

本实验为TCP客户/服务器实验。实验内容:TCP echo客户/服务器设计与实现。TCP echo客户/服务器程序完成以下功能:

客户从标准输入读一行文本,写到服务器上;服务器从网络输入读取此行,并回射(echo)给客户;客户读此回射行,并将其写到标准输出。 六、实验步骤

1、 总体设计

客户程序从标准输入读一行文本,写到服务器程序上;服务器程序从网络输入读取此行,并回射给客户程序;客户程序读此回射行,并将其写到标准输出。

2、 详细设计

stdinstdoutfgetsTCP客户fputsreadlinewritenwritenreadlineTCP服务器TCP客户-服务器程序所用套接口函数

1)服务器main函数

创建套接口,捆绑服务器的众所周知端口服务器阻塞于accept调用,等待客户连接的完成对于每个客户,函数fork派生出一个子进程由此子进程关闭监听套接口,父进程关闭已连接套接口,子进程调用函数str_echo来处理客户

2)服务器str_echo函数 readline从套接口读下一行客户关闭连接(正常情况)YN该行由writen回射给客户

3)客户main函数

创建套接口,装填网际套接口地址结构 connect建立与服务器连接调用str_cli函数完成客户处理的剩余工作

4)客户str_echo函数 fgets读一行文本fgets遇到文件结束或错误YNwriten将此行发送到服务器readline从服务器读回射行,fputs将其写到标准输出

Serv

#include

#include

#include

#include

#include

#define MAXLINE 4096

#define LISTENQ 1024 /* 2nd argument to listen() */

#define SERV_PORT 9877

#define SA struct sockaddr

void str_echo(int);

ssize_t readline(int, void *, size_t);

static ssize_t my_read(int, char *); int

main(int argc, char **argv)

{

int listenfd, connfd;

pid_t childpid;

socklen_t clilen;

struct sockaddr_in cliaddr,servaddr;

if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

printf("socket error.n");

exit(1);

}

bzero(&servaddr, sizeof(servaddr));

_family = AF_INET;

_addr.s_addr = htonl(INADDR_ANY);

_port = htons(SERV_PORT);

if (bind(listenfd, (SA *)&servaddr, sizeof(servaddr)) < 0) {

printf("bind error.n");

exit(1);

}

if (listen(listenfd,LISTENQ) < 0) {

printf("listen error.n");

exit(1);

}

for( ; ;) {

clilen = sizeof(cliaddr);

if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {

printf("accept error.n");

exit(1);

}

if((childpid = fork()) == 0) {

close(listenfd) ;

str_echo(connfd);

exit(0);

}

close(connfd);

}

}

void

str_echo(int sockfd)

{

ssize_t n;

char line[MAXLINE];

for ( ; ; ) {

if ( (n = readline(sockfd, line, MAXLINE)) == 0)

return; /* connection closed by other end */

write(sockfd, line, n);

}

}

/*end str_echo*/

ssize_t

readline(int fd, void *vptr, size_t maxlen)

{

int n, rc;

char c, *ptr;

ptr = vptr;

for (n = 1; n < maxlen; n++) {

if ( (rc = my_read(fd, &c)) == 1) {

*ptr++ = c;

if (c == 'n')

break; /* newline is stored, like fgets() */

} else if (rc == 0) {

if (n == 1)

return(0); /* EOF, no data read */

else

break; /* EOF, some data was read */

} else

return(-1); /* error, errno set by read() */

}

*ptr = 0; /* null terminate like fgets() */

return(n);

}

/* end readline */

static ssize_t

my_read(int fd, char *ptr)

{ static int read_cnt = 0;

static char *read_ptr;

static char read_buf[MAXLINE];

if (read_cnt <= 0) {

again:

if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {

if (errno == EINTR)

goto again;

return(-1);

} else if (read_cnt == 0)

return(0);

read_ptr = read_buf;

}

read_cnt--;

*ptr = *read_ptr++;

return(1);

}

/*end ssize_t*/

Cli

#include

#include

#include

#include

#include

#define MAXLINE 4096

#define LISTENQ 1024

#define SERV_PORT 9877

#define SA struct sockaddr

void str_cli(FILE *,int);

ssize_t readline(int, void *, size_t);

static ssize_t my_read(int, char *);

int

main(int argc, char **argv)

{

int sockfd;

struct sockaddr_in servaddr;

if (argc != 2) {

printf("usage:tcpcli01 ");

exit(1);

/* 2nd argument to listen() */ }

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

printf("socket error.n");

exit(1);

}

bzero(&servaddr, sizeof(servaddr));

_family = AF_INET;

_port = htons(SERV_PORT);

inet_pton(AF_INET, argv[1], &_addr);

if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0) {

printf("connect error.n");

exit(1);

}

str_cli(stdin, sockfd);

exit(0);

}

void

str_cli(FILE *fp,int sockfd)

{

char sendline[MAXLINE], recvline[MAXLINE];

while (fgets(sendline,MAXLINE, fp) != NULL) {

write(sockfd, sendline, strlen(sendline));

if (readline(sockfd, recvline, MAXLINE) == 0) {

printf("str_cli:server terminated prematurely.n");

exit(1);

}

fputs(recvline, stdout);

}

}

/*end str_cli */

ssize_t

readline(int fd, void *vptr, size_t maxlen)

{

int n, rc;

char c, *ptr;

ptr = vptr;

for (n = 1; n < maxlen; n++) {

if ( (rc = my_read(fd, &c)) == 1) { *ptr++ = c;

if (c == 'n')

break; /* newline is stored, like fgets() */

} else if (rc == 0) {

if (n == 1)

return(0); /* EOF, no data read */

else

break; /* EOF, some data was read */

} else

return(-1); /* error, errno set by read() */

}

*ptr = 0; /* null terminate like fgets() */

return(n);

}

/* end readline */

static ssize_t

my_read(int fd, char *ptr)

{

static int read_cnt = 0;

static char *read_ptr;

static char read_buf[MAXLINE];

if (read_cnt <= 0) {

again:

if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {

if (errno == EINTR)

goto again;

return(-1);

} else if (read_cnt == 0)

return(0);

read_ptr = read_buf;

}

read_cnt--;

*ptr = *read_ptr++;

return(1);

}

/*end ssize_t*/

总结:实验对于我们来说是很重要的,经过这几次实验,我已经大致了解了TCP/IP的工作原理,知道了要想实验客户机和服务器的连连通,具体的步骤是什么。在试验中我们组遇到了很大的困难,几乎每一个步骤都会遇到很多问题,不多最后还是凭借大家的力量一一克服了,感谢老师对我们的帮助。