首页 网络课程设计书

网络课程设计书

举报
开通vip

网络课程设计书 计算机网络课程 设计实验报告 目 录 一:实验内容和要求-----------------------------------------------------------3 二: 实验环境--------------------------------------------------------------------4 三: 程序的需求分析与逻辑框图------------------------------------------4 四: 程序核心功能的实现机制-----...

网络课程设计书
计算机网络课程 设计实验报告 目 录 一:实验内容和要求-----------------------------------------------------------3 二: 实验环境--------------------------------------------------------------------4 三: 程序的需求 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 与逻辑框图------------------------------------------4 四: 程序核心功能的实现机制---------------------------------------------9 五: 程序源代码:(核心部分) ------------------------------------------24 六: 程序扩展功能的需求分析与实现--------------------------------- 34 七: 实验数据,结果分析---------------------------------------------------- 35 八: 实验总结----------------------------------------------------------------- 52 九: 同组人分工情况--------------------------------------------------------53 一:实验内容和要求 1.实验一:数据包的捕获与分析 实验内容: 本实验通过Wireshark软件的安装使用,监控局域网的状态,捕获在局域网中传输的数据包,并结合在计算机网络课程中学习到的理论知识,对常用网络 协议 离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载 的数据包做出分析,加深网络课程知识的理解和掌握。 实验要求: · Wireshark软件的安装; · Wireshark软件的启动,并设置网卡的状态为混杂状态,使得Wireshark可以监控局域网的状态; · 启动数据包的捕获,跟踪PC之间的报文,并存入文件以备重新查; · 设置过滤器过滤网络报文以检测特定数据流; · 对常用协议的数据包的报文 格式 pdf格式笔记格式下载页码格式下载公文格式下载简报格式下载 进行分析,利用协议分析软件的统计工具显示网络报文的各种统计信息。 2.实验二: 网络层实验—Ping程序的设计与实现 实验内容: 本实验为ICMP实验。实验内容为Ping命令实现的扩充。 实验要求: 在给定的Ping程序的基础上做如下功能扩充: · -h 显示帮助信息 · -b 允许ping一个广播地址,只用于IPv4 · -t 设置ttl值,只用于IPv4 · -q 安静模式。不显示每个收到的包的分析结果,只在结束时,显示汇总结果 3.实验三: 应用层实验—简单聊天程序的设计与实现 实验内容: 本实验要求设计并实现一个简单的聊天程序,包括服务器实现和客户端实现. 实验要求: · 使用MSN或者QQ,分析聊天程序的功能需求; · 在给定的参考程序的基础上,参考MSN或者QQ,对功能做出扩充,不局限于以下的范围: · 在客户端界面上显示所有联入聊天服务器的用户; · 支持两个用户之间的聊天; · 支持增加好友的功能,好友上线时如果该用户在线,则做出提醒; · 增加用户的个人信息修改、保存和查询; · 在聊天内容中支持中文; · 在聊天内容中支持图片等多媒体信息; · 支持在用户之间传输文件等附件; 其他扩展。 二:实验环境 · window 7系统的计算机 · Linux虚拟机 · 路由器,调试解调器 · Wireshark抓包软件 · Eclipse java 开发环境 三:程序的需求分析与逻辑框图 1、 实验一: 1.需求分析 通过Wireshark软件,捕获局域网中的数据包。通过对其中每个包的分析,我们可以系统的了解局域网的状态,进行实时监控。 2.逻辑框图 2、 实验二: 1.需求分析 程序分为两大部分:一部分读取收到的所有消息,并输出ICMP Echo replay消息,另一部分每个一秒钟发送一个Echo消息。另一部分由SIGALARM信号每秒驱动一次。 2.逻辑框图 Ping程序函数概貌 1)main函数 2)readloop函数 3)proc函数 4)send函数 3、 实验三: 1.需求分析 本实验要实现的是一个客户端服务器聊天程序,与我们所熟悉的QQ,微信,Line聊天程序类似,可以参照它们在基本的功能框架上来实现功能的扩展。 扩展功能  1.我们在网络媒体上的交流主要是通过文字,声音,图片,文件等媒介实现的。所以要在原来的基础上增加中文,图片,文件的相互传送。 2.为了友好界面,我们应该设计用户连接,登录,聊天界面,更加实用,便于理解。 3.客户端与服务器是多对一的关系,一个服务器可以连接多个客户端。 4.应该每个用户单独设计用户名,密码验证以及注册功能 5.服务器要与数据库进行连接,更新实时信息,及时的写入读取 6.在用户信息显示栏显示好友上线信息,备注信息。 2.逻辑框图 整体模块设计 聊天程序 客户端内核 客户端界面 服务器 客户端接收,发送信息机制 Accept ()侦听,建立连接,新建聊天线程。接收发送端客户的信息,将信息发给确定的接受者。更新数据库 用户信息,好友信息显示 好友聊天对话框 连接,登录,注册界面 客户端界面设计框图 1)初始登录,连接界面 2)每个用户属性信息,好友信息界面 3)好友之间聊天Dialog.java对话框 客户端与服务器信息交互逻辑框图 客户端与客户端之间信息的发送 客户端的登录,注册,信息更新 四、程序核心功能的实现机制 1、实验一 根据各个报文的报文格式,逐个分析各报文的含义及内容 以太网帧格式 IEEE802.3报文格式 IPv4包头格式 IPv6包头格式 TCP包头格式 UDP报文格式 2.实验二: 1.读取命令行设计: while((ch=getopt(argc,argv,"i:c:p:s:l:abt:w:qI:S:h"))!=-1){ Switch(ch){ Case’i’:.............,break Case’c’:.............break Case ‘p’:.......... break .......... } 用getopt函数来读取命令行中的命令,用switch-case语句来分别完成每个字母命令所对应的设置。 2. -i命令设计:设置interval 当case’i’时,ctrlintercal会等于后面的参数值,在alarmproc 定时器处理函数中, if(sendinterval==ctrlinterval) { sendpacket(); sendinterval=0; } sendinterval++; 如果sendintercal等于ctrlinterval即间隔的话,就发送包并置0,否则就加1. 实现控制时间间隔的目的。 3. --c命令设计:设置总发包数 Ctrlsendc为设置的发包数,在sendpacket()中, if(ctrlcode[2]==1)//设置了总发包数 { if(sendcount==ctrlsendc) { // endprint(SIGINT); return; } 如果发包数达到了设置的发包数,就会终止发包,达到控制发包数的目的 4. -p 命令设计:设置pattern ctrlcode[3]=1; patternlen=strlen(optarg);//pattern 长度 temppattern=malloc(patternlen); strncpy(temppattern,optarg,patternlen);//复制optarg内容到temp if(patternlen%2!=0) { temppattern[patternlen]=temppattern[patternlen-1]; temppattern[patternlen-1]='0'; patternlen++; temppattern[patternlen]='\0'; } if(setpattern(temppattern)==-1) { err_proc("patterns must be specified as hex digits!"); } 5. -s命令设计: 设置包大小 ctrlpacketsize=atoi(optarg); if(ctrlpacketsize>=8) { datalen=ctrlpacketsize; //icmp头后边的数据长度 } else{ err_proc("packet size must be >= 8!"); } ctrlpacketsize为设置的参数值,并且不能小于8,并赋予给datalen, 6. -l命令设计:设置预发包数 ctrlcode[5]=1; ctrlpreload=atoi(optarg); //设置第一次发包数量 user=getpwuid(getuid()); //得到当前用户权限标识 if(user->pw_gid!=0) //如果当前用户不是root权限,第一次发包 数不能大于3 { if(ctrlpreload>3) { err_proc("user must be root can set >=3!\n");//大于3就会显示错误 } } 7. -a命令设计: 发出声音 若ctrlcode[6]=1,就会调用下面的函数 void my_sound( { printf("%c",soundcode);//soundcode=0x07 } 8. -b 命令设计:允许ping广播地址 if(ctrlcode[7]==1)//ctrlcode=7 -b allow ping broadcast address { setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &size, sizeof(size)); } 9. -t 命令设计:设置ttl ctrlcode[8]=1; ctrlttl=atoi(optarg); //设置所发包的ttl值 ctrlttl为后面的参数值 并在运行的时候进行相关的设置 if(ctrlcode[8]==1)//ctrlcode=8 -t set ttl { setsockopt(sockfd, IPPROTO_IP, IP_TTL, (const char*)&ctrlttl, sizeof(ctrlttl)); } 10. -w 命令设计:设置deadline ctrlcode[9]=1; ctrldeadline=atoi(optarg); ctrldeadline为后面的参数值 在alarmproc函数中 if(ctrlcode[9]==1) { if(waitinterval==ctrldeadline)//设置了deadline { deadline(); } waitinterval++; } 通过waitinterval和ctrldeadline进行时间的控制,当到达deadline时,执行deadline子函数 void deadline() { printf("time out!\n"); kill(pid,SIGINT); } 进而结束进程。 11. -q 命令设计:设置安静模式 ctrlcode[10] 在ipv4和ipv6处理函数中 void proc_v4(char *ptr, ssize_t len, struct timeval *tvrecv) //ipv4处理函数 { .......... if(ctrlcode[10]!=1)//不是安静模式则输出信息,否则不输出 {printf("%d bytes from %s: seq=%u, ttl=%d, rtt=%.3f ms\n", icmplen, sock_ntop_host(pr->sarecv, pr->salen), icmp->icmp_seq, ip->ip_ttl, rtt); } 在ipv6处理函数中类似,在此不粘贴了。 12. -I命令设计:设置源IP ctrlcode[11]=1; ctrlsource=optarg 在void setipheader(int icmphlen)中实现 { //填充IP头 iph.verlen=0x45; iph.total_len=htons(sizeof(iph)+icmphlen); //16位总长度(字节) iph.id=1; //16位标识 iph.frag=0; //3位标志位 iph.ttl=128; //8位生存时间TTL iph.protocol=IPPROTO_ICMP; //8位协议(TCP,UDP…) iph.checksum=0; //16位IP首部校验和 iph.sourceIP=inet_addr(ctrlsource); //32位源IP地址 iph.destIP=inet_addr(host); //32位目的IP地址 } 13. -S 命令设计:设置sndbuf ctrlcode[12]=1; ctrlsndbuf=atoi(optarg);//大小等于后面的参数 if(ctrlsndbuf<=0) { printf("error:bad sndbuf value!\n");//如果小于等于0就会报错 exit(0); } 在mainloop函数中实现 sndbufsize=ctrlsndbuf*84*1024; 14. -h命令设计:显示帮助 ctrlcode[13]=1 在下面的函数中实现 if(ctrlcode[13]==1) { print_instruction(); return 0; } void print_instruction() { printf("Usage: myping [-abqhV] [-c count] [-i interval] [-w deadline]\n"); printf(" [-p pattern] [-s packetsize] [-t ttl] [-l preload]\n"); printf(" [-I source] [-S sndbuf] destination\n"); printf("explain:\n"); printf("-a Audible ping.\n\n"); printf("-b Allow pinging a broadcast address.\n\n"); printf("-q Quiet output. Nothing is displayed except the summary \n"); printf(" lines at startup time and when finished.\n\n"); printf("-h Show help and explain.\n\n"); printf("-c count\n"); printf(" Stop after sending count ECHO_REQUEST packets.\n\n"); printf("-i interval\n"); printf(" Wait interval seconds between sending each packet.\n\n"); printf("-w deadline\n"); printf(" Specify a timeout, in seconds, before ping exits regardless of\n"); printf(" how many packets have been sent or received.\n\n"); printf("-p pattern\n"); printf(" Specify up to 16 hex bytes to fill out the packet you send.\n\n"); printf("-s packetsize\n"); printf(" Specifies the number of data bytes to be sent.\n\n"); printf("-t ttl\n"); printf(" Set the IP Time to Live.\n\n"); printf("-l preload\n"); printf(" If preload is specified, ping sends that many packets not \n"); printf(" wait-ing for reply. Only the super-user may select preload\n"); printf(" more than3.\n\n"); printf("-I source\n"); printf(" Set source address to specified interface address.\n\n"); printf("-S sndbuf\n"); printf(" Set socket sndbuf. If not specified, it is selected to \n"); printf(" buffer not more than one packet.\n\n"); } 3、实验三: 1)客户端界面 连接,登录,注册界面 首先根据初始的界面设计,进行布局设置,利用BorderLayout,JPanel, JTextField,JButton等控件摆出连接界面的布局,并在按钮,输入框中添加事件监听,键盘监听以及焦点事件监听addActionListener(),addKeyListener(),addFocusListener()。 addFocusListener()焦点事件监听 基本框架中已经给出,包括 public void focusGained(FocusEvent e) public void focusLost(FocusEvent e) addKeyListener()键盘事件监听 包括keyPressed(KeyEvent arg0) keyReleased(KeyEvent arg0) keyTyped(KeyEvent e) 设置键盘响应(ENTER) 当name框按下enter,焦点到msgWindow,当在host框按下enter键,焦点到port框,当在port框按下enter键,焦点到nick框。 addActionListener()按钮事件监听 用户信息,好友信息显示界面 根据初始的界面设计,进行布局设置,利用BorderLayout,JPanel,JScrollPane, JTextField,JButton等控件摆出用户界面的布局,并在按钮,输入框中添加事件监听,键盘监听以及焦点事件监听addActionListener(),addKeyListener(),addFocusListener()。 与上面的设置类似,之后又增加了好友信息的显示,用两个字符数组String templisto[],String templistf[]来存储用户的用户属性信息以及好友的用户,备注姓名信息。用两个列表lso = new List();lsf = new List();来显示所有在线的用户以及好友用户信息。 事件监听: 用户与用户之间聊天显示界面 同样根据初稿的界面设计,进行布局设置,利用BorderLayout,JPanel,JScrollPane, JTextField,JButton等控件摆出用户界面的布局,并在按钮,输入框中添加事件监听,键盘监听以及焦点事件监听addActionListener(),addKeyListener(),addFocusListener()。添加函数SetTtype() 显示接收到的图片。 事件监听:主体为三个文字,图片,文件按钮的监听 2)客户端内核 ClientKernel() 实现的主要功能:1.与服务器建立连接,创建套接口 2.接收来自界面发送过来的信息,并将其发送给服务器3.接收来自服务器的信息,并输出到响应显示对话框。 1. connect();建立连接,初始化套接口sock = new Socket(serverAd, port); sock2 = new Socket(serverAd,port+200); sock2用于文件的传输发送 2.接收来自三个用户端界面的消息getMsgFrom_UserClient(),getMsgFrom_ Dialog()getMsgFrom_connect这三个函数表示。getMsgFrom_ Dialog()如果是文字信息[msg]直接发送给服务器,如果是[FILE]文件,利用socket2将信息文件名发送服务器;getMsgFrom_connect()获取服务器地址,端口号,用户名以及密码;如果是[CON]注册信息,向服务器发送 [CON]"+"L "+用户名+密码,如果是[REG]登录信息,向服务器发送[CON]"+"R "+用户名+密码, 3.客户端接收或者发送信息 ClientMsgSender extends Thread {} ClientMsgListener extends Thread{} ClientMsgSender extends Thread {}客户端发送信息到服务器 具体流程图如下图所示 客户端信息发送流程图 3. ClientMsgListener extends Thread接收来自服务器的信息 客户端接收信息流程图 ClientFilesender()客户端文件信息的发送 Class ClientFileListener()客户端文件信息的接收 3)服务器端MainSever() 初始化服务器套接口server,server2,,调accept()函数进行阻塞侦听,如果有客户端请求,建立连接socket2 = server2.accept(); socket = server.accept();为每个新建连接的用户新建一个Chat_Thread()线程,并添加到线程池,用bMan进行统一管理。 Chat_Thread()流程 如下图所示 Chat_Thread()处理流程图 4)数据库的设计 用户信息表(用户名,密码,是否在线,爱好,性别,年龄) 好友关系表(A,B,备注姓名) 五、程序源代码(核心部分) 1、实验二 如上核心的设置机制处所示,在核心分析的同时已经给出了核心代码,在这就不再重复了 2、实验三 1)服务器核心代码 服务器接收来自客户端信息并做相应处理 public void run() { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); ///加载驱动程序 } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { reader = new BufferedReader(new InputStreamReader( socket.getInputStream())); ///输入流放到buffer缓冲区 writer = new PrintWriter(socket.getOutputStream(), true);/////使用PrintWriter建立一个发送信息的通道 String msg; while (isrunning) { if ((msg = reader.readLine()) != null) { if (msg.startsWith("[LOGIN]")) { username = msg.substring(7);//获取用户名 reflash(true, true, true, false); } else if (msg.startsWith("[FIREND]")) { // 添加好友表项 String bfirend = msg.substring(8); msg_firend(bfirend); } else if (msg.startsWith("[CHANGE]")) { // 修改好友备注“[CHANGE]好友 备注” msg_change(msg); } else if (msg.startsWith("[UPDATE]")) { msg_update(msg); } else if (msg.startsWith("[MSG]")) { // 发送信息到指定对象 System.out.print(msg); bMan.sendToAll(msg); } else if (msg.startsWith("[FILE]")) { // 发送文件 String temp = msg.substring(6); String type = temp.substring(0, temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ")+1); String listener = temp.substring(0,temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ")+1); String sender = temp.substring(0, temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ") + 1); getfile(type,msg); //接收 bMan.sendToO(listener,msg); sendfile(type,msg,listener); ///发送 System.out.println(socket2.isClosed()); } else if (msg.startsWith("[CON]")){ msg_connect(msg); } else if (msg.startsWith("[EXIT]")) { this.isrunning = false; bMan.sendToS(this, msg); bMan.remove(this); reflash(false, true, false, true); break; } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { bMan.remove(this); if (reader != null) reader.close(); if (writer != null) writer.close(); if (socket != null) socket.close(); reader = null; writer = null; socket = null; System.out.println(username + "已下线..."); System.out.println("连接人数: " + bMan.size()); } catch (Exception e) { } } } private void msg_connect(String msg){ ////提取用户名,密码,查找数据库,登录 String temp = msg.substring(5); String mark = temp.substring(0, temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ")+1); String username = temp.substring(0,temp.indexOf(" ")); String password = temp.substring(temp.indexOf(" ")+1); try { Connection con; con = DriverManager.getConnection("jdbc:odbc:mychatdb", "", "");///与数据库建立连接 java.sql.Statement stmt = con.createStatement(); if(mark.equals("L")){ ///登录 ResultSet rset = stmt .executeQuery("select * from user where username = '" + username + "' AND password ='"+password +"'"); if (rset.next()) { bMan.sendToS(this, "[SUCCESS]"); } } else if(mark.equals("R")){ ///insert,新用户注册 stmt.executeUpdate("insert into user values('" + username + "','" + password + "',1,' ',' ',0);"); bMan.sendToS(this, "[SUCCESS]"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void msg_update(String msg) { ///修改用户的属性信息 // TODO Auto-generated method stub String temp = msg.substring(8); String mark = temp.substring(0, temp.indexOf(" ")); String newinfo = temp.substring(temp.indexOf(" ") + 1); try { Connection con; con = DriverManager.getConnection("jdbc:odbc:mychatdb", "", ""); java.sql.Statement stmt = con.createStatement(); if (mark.equals("h")) { stmt.executeUpdate("update user set habit = '" + newinfo + "' where username = '" + username + "'"); } else if (mark.equals("s")) { stmt.executeUpdate("update user set sex = '" + newinfo + "' where username = '" + username + "'"); } else if (mark.equals("a")) { stmt.executeUpdate("update user set age = '" + newinfo + "' where username = '" + username + "'"); } reflash(false, true, false, false); con.close(); stmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void msg_change(String msg) { ////修改备注姓名,更新数据库 // TODO Auto-generated method stub String temp = msg.substring(8); String fname = temp.substring(0, temp.indexOf(" ")); String remark = temp.substring(temp.indexOf(" ") + 1); try { Connection con; con = DriverManager.getConnection("jdbc:odbc:mychatdb", "", ""); java.sql.Statement stmt = con.createStatement(); stmt.executeUpdate("update firend set remark = '" + remark + "' where Afirend = '" + username + "' AND Bfirend = '" + fname + "'"); stmt.close(); con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } reflash(false, false, true, false); } private void msg_firend(String bfirend) { ///增添新的好友关系消息 // TODO Auto-generated method stub try { Connection con; con = DriverManager.getConnection("jdbc:odbc:mychatdb", "", ""); java.sql.Statement stmt = con.createStatement(); ResultSet rset = stmt .executeQuery("select username from user where username = '" + bfirend + "'"); if (!rset.next()) { bMan.sendToS(this, "[NOUSER]"); //用户不存在 } else { rset = stmt .executeQuery("select * from firend where Afirend = '" + bfirend + "' AND Bfirend = '" + username + "'"); if (rset.next()) { bMan.sendToS(this, "[HAVEI]"); //已经存在 } else { stmt.executeUpdate("insert into firend values('" + username + "','" + bfirend + "','');"); stmt.executeUpdate("insert into firend values('" + bfirend + "','" + username + "','');"); bMan.sendToS(this, "[SHAVE]"); //添加成功 reflash(false, false, true, false); } stmt.close(); con.close(); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ////服务器刷新,更新数据库 private void reflash(boolean istip, boolean isuser, boolean isfirend, boolean isclose) { /////刷新好友表,用户表 // TODO Auto-generated method stub\ String msg1 = ""; String msg2 = ""; ResultSet rset; try { Connection con; msg1 = "[USER]"; msg2 = "[FLIST]"; con = DriverManager.getConnection("jdbc:odbc:mychatdb", "", ""); java.sql.Statement stmt = con.createStatement(); // 修改当前用户的上线状态 if (isuser) { stmt.executeUpdate("update user set isonline = 1 where username = '" + username + "'"); // 查询在线用户的列表 rset = stmt .executeQuery("select username,habit,sex,age from user where isonline = 1"); while (rset.next()) { msg1 = msg1 + rset.getString("username").toString() //显示当前用户列表 + "||" + rset.getString("habit").toString() + "||" + rset.getString("sex").toString() + "||" + rset.getString("age").toString() + "/"; } msg1 = msg1 + ";"; bMan.sendToAll(msg1); } // 列出所有的好友 if (isfirend) { rset = stmt .executeQuery("select Bfirend,remark from firend where Afirend = '" + username + "'"); while (rset.next()) { ///显示好友信息以及备注 msg2 = msg2 + rset.getString("Bfirend").toString() + "::::" + rset.getString("remark").toString() + "/"; } msg2 = msg2 + ";"; bMan.sendToAll( msg2); } // 发送好友上线提醒 if (istip) { rset = stmt .executeQuery("select Bfirend from firend where Afirend = '" + username + "'"); while (rset.next()) { String msg3 = "[FUSER]" + username; String fname = rset.getString("Bfirend").toString(); bMan.sendToF(fname, msg3); ///发送上线提醒 } } if (isclose) { stmt.executeUpdate("update user set isonline = 0 where username = '" + username + "'"); } stmt.close(); con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 客户端内核的核心代码ClientKernel().java 读取服务器发过来的消息并做相应的处理 public void run() { try { BufferedReader reader = new BufferedReader( //实例化数据流 new InputStreamReader(s.getInputStream())); while (running) { if(!isfile){ String msg; String temp; while ((msg = reader.readLine()) != null) { ///消息不为空的话 String sender; String listener; if (msg.startsWith("[MSG]")) {////读取信息头的关键字来识别为何种信息 temp = msg.substring(5); ///substring从消息中提取发送者,接受者,消息 listener = temp.substring(0, temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ") + 1); sender = temp.substring(0, temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ") + 1); System.out.print(listener + sender + temp); ///系统输出接收者,发送者,内容 this.ck.storeMsg(listener, sender, temp,""); //调用storeMsg()显示到对话框 } else if (msg.startsWith("[FILE]")) { ///文件信息提取 System.out.print(msg); temp = msg.substring(6); String type = temp.substring(0, temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ")+1); listener = temp.substring(0,temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ")+1); sender = temp.substring(0, temp.indexOf(" ")); temp = temp.substring(temp.indexOf(" ") + 1); System.out.print(temp); cfl.getfile(temp); System.out.println(sock2.isClosed()); this.ck.storeMsg(listener,sender, temp ,type); } else if (msg.startsWith("[SUCCESS]")){ //初始登录成功 isConnected = true; connect.setVisible(false); } else if (msg.startsWith("[FUSER]")) { //提示好友上线 temp = msg.substring(7); this.ck.setLabelTxt("嘿嘿,您的好友 " + temp + " 已经上线了哟"); } else if (msg.startsWith("[NOUSER]")) { this.ck.setLabelTxt("对不起,该用户不存在"); } else if (msg.startsWith("[HAVEI]")) { this.ck.setLabelTxt("亲,你们已经是好友了"); } else if (msg.startsWith("[SHAVE]")) { this.ck.setLabelTxt("恭喜您,成功添加好友,现在你们可以对话了"); } else if (msg.startsWith("[USER]")) { ////增加在线用户列表 int counto = 0; String onlineuser; temp = msg.substring(6); while (!temp.equals(";")) { onlineuser = temp.substring(0, temp.indexOf("/")); ck.setTemplisto(onlineuser, counto); temp = temp.substring(temp.indexOf("/") + 1); counto++; } this.ck.setListLengtho(counto); } else if (msg.startsWith("[FLIST]")) { ///增加好友列表项 int countf = 0; String firend; temp = msg.substring(7); while (!temp.equals(";")) { firend = temp.substring(0, temp.indexOf("/")); ///用户名 ck.setTemplistf(firend, countf); temp = temp.substring(temp.indexOf("/") + 1); ///备注 countf++; } this.ck.setListLengthf(countf); } else if (msg.startsWith("[EXIT]")) { ///退出 this.ck.dropMe(); reader.close(); System.exit(0); } else System.out.print("lose message"); } } } reader.close(); stop(); } catch (IOException ioe) { ioe.printStackTrace(); } finally { hasStoped = true; } } } } 六、程序扩展功能的需求分析与实现 1、实验二 通过设置ctrlcode控制数组,用数组的1位数字来控制每一个扩充的功能,并与命令行中的字母相对应。用getopt来不断获取命令行中的字母指令及其后面的参数,与ctrlcode相配合,来改变各个扩充功能在相应子函数中的参数,从而达到实现扩展功能的目的。 ①-i设置interval:用ctrlcode[1]控制,ctrlinterval表示间隔,为后面参数的值,并赋予 sendinterval. ②-c 设置总发包数:用ctrlcode[2]控制,ctrlsendc表示发包数,其值为后面的参数值 ③-p 设置pattern:用ctrlcode[3]控制,pattern长度为后面的参数值 ④-s 设置包大小:用ctrlcode[4]控制,ctrlpacketsize表示包大小,其值为后面的参数值,并赋予datalen ⑤-l 设置预发包数:用ctrlcode[5]控制,ctrlpreload为后面的参数值,表示预先发的数量 ⑥-a 发出声音:用ctrlcode[6]控制 ⑦-b 允许ping广播地址:用ctrlcode[7]控制 ⑧-t 设置ttl:用ctrlcode[8]控制,ctrlttl表示ttl,其值为后面的参数 ⑨-w 设置发包的最后的时间,deadline:用ctrlcode[9]控制,ctrldeadline为后面的参数值 ⑩-q 设置安静模式:用ctrlcode[10]控制,在ipv4处理数据的过程中,如果ctrlcode[10]=1就不会立即显示出信息,否则就显示 ⑪-I 设置源IP:用ctrlcode[11]控制,IP值为后面的参数值 ⑫-S 设置sndbuf:用ctrlcode[12]控制,buf值为后面的参数值 13- -h 显示帮助:用ctrlcode[13]控制 2.实验三 1. 要想在客户端界面上显示所有联入聊天服务器的用户, 支持增加好友的功能,好友上线时如果该用户在线,则做出提醒, 增加用户的个人信息修改、保存和查询的需求的化,需要单独设计一个用户界面UserClient()来显示用户的属性信息,好友信息。增加好友的时候需要服务器与数据库连接,进行实时更新。用户属性信息,好友备注需要实时监听,修改更新。 2.用户的登录注册,信息修改需要与数据库进行连接,可以采用Office的Access数据库,建立用户信息表, 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 用户的爱好,性别和年龄,建立好友关系表,记录用户之间的好友关系以及备注姓名。设定数据源ODBC,建立与服务器相连接,进行实时更新,记录,增加新的信息。 3.文件,图片的传送,可应通过DataOutputStream, DataInputStream FileInputStream, FileOuputStream,进行读取和写入,读取和写入的时候可以通过字节流数组来暂存文件的数据信息。 4.客户端,服务器发送接收消息的时候可以通过消息头部的标识符关键字[MSG],[CON],[FILE][FRIEND],[EXIT]等等对消息加以区分,判断消息的类别,做出相应的回应和处理。 5.文件消息,文字消息建立不同套接口socket,socket2区分 七、实验数据、结果分析 1、实验一 报文分析及捕获结果 以太网报文捕获结果: Ethernet II f f ff ff ff ff ff 目标MAC地址 8c a9 82 b9 oe 88 源MAC地址 08 00 类型(0x0800为IP) Ethernet II 5c 63 bf 6a e6 a8 目标MAC地址 44 2a 60 fb 39 56 源MAC地址 08 00 类型(0x0800为IP) IEEE802.3的捕获结果 IEEE 802.3 01 80 c2 00 00 00 目标MAC地址 3c e5 a6 87 dd b0 源MAC地址 00 84 长度132 IPV4报文 IP 4 版本号 20bytes 头部长度 78 总长度78字节 0x052b Identification标识 0x00 Flags标志 0 Fragment offset位移 06 协议为TCP 64 TTL UDP Protocol协议 0xd01c 头部校验和 172.24.37.40 源地址 172.24.39.255 目的地址 IPV6报文 版本号 6 Traffic class 0x00000000 Flowable 0x00000000 Payload length 30 Next header UDP Hop limit 1 源地址 fe80:7856:90f9:5b85:641c 目的地址 ff002::1:3 TCP报文 源端口号 http(80 ) 目的端口号 49914 S equence number 0 确认序列号 1 头部长度 32bytes F lag 0x12(SYN,ACK) 窗口大小 8192 校验和 0xebae Opions 12bytes UDP报文 UDP 3a1b 源端口14875 1f44 目的端口8004 002b 长度43字节 2c84 效验和0x2c84 ICMP报文 ICMP 08 类型ECHO Request 00 代码0 4d 59 效验和 00 01 标识符0x0001 00 002 序列号0x00002 2.报文过滤捕获 捕获前过滤,过滤出 TCP only 的TCP协议报文 捕获后过滤,选出所有Protocol是ICMPV6的报文 过滤表达式 2、实验二 1. 编译ping.c 2. 用linux 本身的ping命令ping 地址表示网络联通 3. 用myping来进行操作 4. -i命令,设置时间间隔,此处设置为5,在运行过程中可以明显感觉到有时间的延迟 5. -c命令,设置总发包数量,此处设置为6 6. -p 设置pattern,-p ff 全部用 1 填充信息包 7. -s 设置包大小,此处设置为64 8. -l 设置预发包数,此处设置为9 9. -a 发出声音 10. -b 允许ping广播地址 11. -t 设置ttl 设置为100时可以ping通,设置为10就没有反应 12. -w 设置发包的最后的时间 设置为5 13. -q 设置安静模式 14. -I 设置源IP 15. -S 设置sndbuf,设置为2 16. -h 显示帮助 4、 实验三 1. 服务器启动 运行 TempServer (),系统输出创建成功 2.登陆界面 输入用户名,密码,服务器经数据库查询后,返回登录成功或失败 3.新用户注册 成功注册登录成功 新用户注册 输入 用户名 密码 新用户注册,数据库及时的更新处理 4.用户信息,好友信息显示界面 用户许飞的好友列表 已经上线的用户 5.修改好友备注姓名 修改信息输入区 修改之后 修改之前 6.修改客户个人属性信息 修改之前 修改后 修改后及时的更新 要修改的内容 7.添加好友 添加已经存在的好友,会进行提示 添加不存在的用户,进行错误提示 添加好友成功,好友列表更新 8.用户之间相互聊天 两个用户之间对话,双方都能接收到相应的信息,并成功在自己的聊天框,对方聊天框显示 客户端之间图片的传送 许飞向晨曦发送图片 对方成功接收,并显示 客户端之间相互传送文件,对方成功接收,系统输出客户端已接收,在相应的存储地方D盘成功显示 成功接收 接收到的图片,文件缓存地 八、总结 这次的计算机网络课程设计,使我们收获颇多。首先试验一的WireShark抓包实验,我们在TCP-IP以及下一代互联网中已经学习过,所以实验一做起来很容易。之后对报文进行了详细的分析。还有过滤前条件的设置应该在capture options中提前进行设置,同时也具体了解到了一些报文如IP,TCP,UDP, ICMP等报文的格式。 实验二为ping命令的扩展,我们在老师提供的ping命令模板之下,做了一些功能的扩展。 在开始阶段,我们在一起学习研究ping命令的功能和使用方法,基本了解了需求之后,接着开始实验环境的搭建。由于Linux是装在虚拟机上的,联网的问题困扰了我们挺久的时间,在查阅了网上的 资料 新概念英语资料下载李居明饿命改运学pdf成本会计期末资料社会工作导论资料工程结算所需资料清单 后才完成好。所有的准备工作完成之后,便开始模板的了解与研究,这一段是最花费我们时间的。在ping命令中,出现了许多我们从未接触过的网络方面的函数和方法,在此之前我们只是在网络课上学习了相关的理论知识,但很少有实践的机会。通过几天的时间来阅读相关的书籍和材料,我们慢慢的了解了ping命令中的逻辑、方法和语句的含义,不再像刚开始接触那么一头雾水。 在看完ping命令之后,我们尝试着从最简单的扩展开始做起,在一遍遍的调试当中,形成了最后的成果。这次的实验让我们了解了ping命令运行的基本原理,对计算机网络的实现有了更深的理解,并且也锻炼了我们的自学能力。 实验三是在老师给的框架之上,对聊天程序进行扩展,功能的扩充,我们首先花费一定的时间研究程序的基本框架,之后对客户端部分进行了更多友好界面的填充设计,好友上线,用户属性信息等等功能的添加,相应的服务器部分也添加了一部分信息的处理。在发送图片和文件的时候,因为图片,文字传送的都是字节流,所以我们采用字节数组,输入输出流的方式发送接收。 经过为期一周多的课设,我们既扩展了自己的知识领域,又增加了自己的动手能力,同时增进了同学之间的交流,相互合作的精神,可算收获良多。 九、同组人分工情况 1 � 设置随同Echo请求一起发送的可选数据长度 处理命令行参数 调用readloop处理分组 为SIGALARM信号 建立一个处理程序 处理主机名参数 � 创建套接口 设置套接口缓冲区大小 发送第一个分组 读取返回给ICMP原始套接口的每个分组 记录收到分组的时间 调用proc来处理这些分组 � 获取ICMP头部指针 检查ICMP Echo replay 输出收到的所有ICMP消息 � 构造ICMP消息 计算校验和 发送数据报 � � � 开始 用BufferReader InputStreamReader(S.getInputStream())实例化数据流 Running? Reader.Close() N 结束 Msg=reader.readline不为空 Y 信息头部关键字为[MSG] Y 提取sender,listener,内容调用storeMsg发送到显示对话框 Y 提取sender,listener,内容调用StoreMsg发送到显示框,调用getfile接受,缓存文件 N 信息头部关键字为[FILE] Y 信息头部关键字为[SUCCESS] N 设置连接状态为true,修改数据库登陆成功 Y 信息头部关键字为[FUSER] N 显示好友上的信息 Y 信息头部关键字为[NOUSER] N 用户不存在 Y 信息头部关键字为[HAVING] N 显示已经为好友 Y 信息头部关键字为[SHAVE] N 添加好友成功 Y 信息头部关键字为[USER] N 增加用户列表刷新 Y 信息头部关键字为[FILS] N 增加好友列表刷新 Y 退出 N � � � � 开始 加载数据库驱动程序driver,并将socket的输入流放入BufferReader缓冲区,即reader读者 Is running? 关闭所有链接 N 结束 Reader.readerlline()!=null Y 信息头部关键字[EXIT]? N 信息头部关键字[COO]? N 调用msg-connect()新用户登录,注册 退出 Y Y 信息头部关键字[LONGING]? N 获取用户名,更新数据库reflash() Y 信息头部关键字[FRIEND]? N Rset.Next()向当前线程发送[HAVEI],已经存在 Y 调用msg-friend()子函数,查找数据库 !ret.next()自当前线程发送[NOUSER],用户不存在 If If 自当前线程发送[SAAVE],更新数据库 If 信息头部关键字[CHANGE]? N 调用msg-change()修改备注姓名,更新数据库 Y 信息头部关键字[UPDATE]? N 调用msg-update()与数据库建立连接,更新用户属性信息,更新数据库 Y 信息头部关键字[MSG]? N 以主机名为关键字,查找用户套接口,发送信息 Y 信息头部关键字[MSG]? N N 提取sender-listener,调用getlife接收文字,sendfile发送文件 Y main readloop recvfrom proc sig_alarm send 为SIGALARM 建立 信号处理程序 无限接收循环 每秒发送一个Echo消息
本文档为【网络课程设计书】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
不系舟红枫
从教近30年,经验丰富,教学水平较高
格式:doc
大小:3MB
软件:Word
页数:55
分类:建筑/施工
上传时间:2019-01-22
浏览量:8