CSU计算机网络实验报告.docx

上传人:b****5 文档编号:30077452 上传时间:2023-08-04 格式:DOCX 页数:27 大小:992.99KB
下载 相关 举报
CSU计算机网络实验报告.docx_第1页
第1页 / 共27页
CSU计算机网络实验报告.docx_第2页
第2页 / 共27页
CSU计算机网络实验报告.docx_第3页
第3页 / 共27页
CSU计算机网络实验报告.docx_第4页
第4页 / 共27页
CSU计算机网络实验报告.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

CSU计算机网络实验报告.docx

《CSU计算机网络实验报告.docx》由会员分享,可在线阅读,更多相关《CSU计算机网络实验报告.docx(27页珍藏版)》请在冰豆网上搜索。

CSU计算机网络实验报告.docx

CSU计算机网络实验报告

计算机网络实验报告

学号:

姓名:

班级:

学院:

信息科学与工程学院

指导老师:

实验一:

距离向量路由算法的实现

1.1实验目的

模拟距离向量路由算法的路由表交换过程,演示每轮交换后路由表的变化。

1.2实验内容

要求编程实现距离矢量路由算法的路由表交换过程,并动态演示每轮交换过后路由表的变化情况。

1.3实验原理

距离向量路由算法,使用这个算法的路由器必须掌握这个距离表(它是一个一维排列,即一个向量),它告诉在网络中每个节点的最远和最近距离。

在距离表中的这个信息是根据临近接点信息的改变而时时更新的。

表中数据的量和在网络中的所有的接点(除了它自己本身)是等同的。

这个表中的列代表直接和它相连的邻居,行代表在网络中的所有目的地。

每个数据包括传送数据包到每个在网上的目的地的路径和距离/时间在那个路径上来传输(我们叫这个为“成本”)。

这个在那个算法中的度量公式是跳跃的次数,等待时间,流出数据包的数量等等。

在距离向量路由算法中,相邻路由器之间周期性地相互交换各自的路由表备份。

当网络拓扑结构发生变化时,路由器之间也将及时地相互通知有关变更信息。

每个路由器维护了一张路由表,它以子网中的每个路由器为索引,并且每个路由器对应一个表项。

该表项包含两部分:

为了达到该目标路由器而使用的输出线路,以及到达该目标路由器的时间估计值或者距离估计值。

距离矢量路由算法在理论中可以工作,但在实践中有一个严重的缺陷:

虽然它总是能够达到正确的答案,但是它收敛到正确答案的速度非常慢,尤其是,它对于好消息的反应非常快,但是对于坏消息的反应非常迟缓。

1.4实验步骤

1.4.1编写程序

程序的源代码如下:

#include"stdio.h"

#include"stdlib.h"

#include"alloc.h"

#defineROUTNUM7

typedefstruct

{

intdis;

intfrom;

}RoutNode;

RoutNodedata[ROUTNUM][ROUTNUM];/*路由表*/

voidInitData(FILE*pfile);/*从数据文件读取数据,初始化路由表*/

voidOutputRoutData();/*输出所有的路由表*/

voidCommunication(intrecv,intsend);/*send点向recv点发送自己的路由表*/

voidExchange();/*所有节点进行一次数据交换,更新路由表*/

voidmain()

{

intstart,end,i,j;

FILE*pfile;

pfile=fopen("1.txt","r");

if(pfile==NULL)

{

printf("文件打开错误,按任意键退出.\n");

getch();

return;

}

else

InitData(pfile);

fclose(pfile);

printf("\n路由表初始:

\n");

for(i=0;i

{

printf("%c||",i+65);

for(j=0;j

if(data[i][j].dis>0)

printf("<%c%d>",j+65,data[i][j].dis);

printf("\n");

}

for(i=0;i

{

Exchange();

}

printf("\n路由表交换:

\n");

OutputRoutData();

printf("输入起始路由节点(%d-%d):

",0,ROUTNUM-1);

scanf("%d",&start);

printf("输入终点路由节点(%d-%d):

",0,ROUTNUM-1);

scanf("%d",&end);

if(start==end||start<0||start>6||end<0||end>6)

{

printf("\n输入错误,请按任意键退出\n");

getch();

return;

}

else

{

intcur=start;

inttotal=0;

if(data[start][end].dis<0)

{

printf("没有路由路径发现!

\n");

getch();

return;

}/*endofif*/

printf("%c->",cur+65);

while(data[cur][end].from>=0)

{

total+=data[cur][data[cur][end].from].dis;

printf("%c->",data[cur][end].from+65);

cur=data[cur][end].from;

}/*endofwhile*/

total+=data[cur][end].dis;

printf("%c\n总的路由距离=%d",end+65,total);

getch();

return;

}/*endofelse*/

}

voidInitData(FILE*pfile)

{

charnum[10];

inti=0;

charc;

intm,n;

fseek(pfile,0,0);

for(m=0;!

feof(pfile)&&m<7;m++)

{

for(n=0;!

feof(pfile)&&n<7;n++)

{

while(!

feof(pfile))

{

c=fgetc(pfile);

if(c==',')/*读完一个数字*/

{

num[i]='\0';

data[m][n].dis=atoi(num);

data[m][n].from=-1;

i=0;

break;

}/*endofif*/

elseif((c>='0'&&c<='9')||c=='-')/*如果读到数字或符号*/

{

num[i++]=c;

}/*endofelseif*/

}/*endofwhile*/

}/*endoffor(n=0*/

}/*endoffor(m=0*/

}

voidOutputRoutData()

{

inti,j;

printf("");

for(i=0;i

{

printf("%c",i+65);

}

printf("\n");

for(i=0;i

{

printf("%c",i+65);

for(j=0;j

{

if(data[i][j].dis<0)/*如果无路径*/

printf("-");

else

if(data[i][j].dis>=10)

printf("%d",data[i][j].dis);

else

printf("%d",data[i][j].dis);

if(data[i][j].from<0)/*如果未经过其它节点*/

printf("-");

else

printf("%c",data[i][j].from+65);

}/*endoffor(j=0*/

printf("\n");

}/*endoffor(i=0*/

}

voidCommunication(intrecv,intsend)

{

inti;

for(i=0;i

{

if(data[send][i].dis>0)/*如果send节点到i号节点有路线*/

{

if(data[recv][i].dis<0)/*如果recv到i号节点无路径*/

{

data[recv][i].dis=data[send][i].dis+data[recv][send].dis;

data[recv][i].from=send;

}

elseif(data[recv][i].dis>data[send][i].dis+data[recv][send].dis)

/*如果现有路径比新路径远*/

{

data[recv][i].dis=data[send][i].dis+data[recv][send].dis;

data[recv][i].from=send;

}

}/*endofif*/

}/*endoffor*/

}

voidExchange()

{

inti,j;

for(i=0;i

{

for(j=0;j

{

if(data[i][j].dis>0)/*如果两个节点之间有路径*/

{

Communication(j,i);/*将i号节点的路由表发送给j号节点*/

}/*endofif*/

}/*endoffor(j=0*/

}/*endoffor(i=0*/

}

1.4.2设计思路

程序先定义了一个路由表——RoutNodedata[ROUTNUM][ROUTNUM],路由表的初始信息存储在文件中,程序运行是先调用函数InitData(FILE*pfile)从文件中读取路由表的初始信息,然后输出初始路由表的信息,Communication(intrecv,intsend)函数主要是向邻近节点发送自己的路由表信息,Exchange()函数则根据新路由表信息更新自己的路由表。

当所有的路由表节点都更新一遍后,整个路由表更新完毕。

1.5实验结果分析

1.5.1结果截图

1.5.2结果分析

路由表初始信息从文件读取,根据距离向量路由算法系统自动完成路由表的更新操作,最后任意输入两个路由表接点,则可得出两接点之间的最短路径。

1.6实验心得体会

实验是对我们应用知识的考察,通过它我们能更加了解自己的能力。

这次的实验是网络课实验中最简单的一次,但我做得一点都不好,还没有写软件的概念和思想,程序也写得不好,还没有再实验课上完成的,是后来到寝室才完成的,没有通过老师的检查,幸亏我们的老师心地善良,说不用检查也可以通过。

这个程序只能实现主要的功能,没有界面,也没有什么操作,因能力有限,只能做到这个样子,还望老师见谅。

有空的话我一定好好学习一种编程软件。

实验二网络聊天窗口

2.1实验目的

1,进一步加深对网络底层数据传输过程的理解

2,通过自己动手编写具体的代码,实现实验的要求,提高学生的编程能力

3,熟悉socket编程接口,初步掌握用socket编程接口开发面向连接的网络应用程序的方法。

4,熟悉socket编程接口,初步掌握用socket编程接口开发无连接的网络应用程序的方法。

2.2实验原理

为实现网络聊天的功能,采用WindowsSocket编程,服务器与客户端采用了TCP/IP连接方式,在设计聊天方案时,实行将所有信息发往服务器端,再由服务器进行分别处理的思路,服务器端是所有信息的中心。

由于服务器端要保存用户信息,我们暂时利用文件保存来实现这一功能,这是为了保存较好的可移植性,在没装相应数据库的机子上也能顺利地运行。

在客户端保存用户号码这一功能的实现中,采用了文件系统设计。

在不同的客户间可以实现文件的传输,其原理与信息传送差不多,只不过传输的内容是文件字节流。

 

服务器及客户端的功能可划分为以下模块:

客户端:

1)登陆功能:

建立与服务器的连接并登陆,能显示登陆错误信息。

(由于本项目是作者09年时出于兴趣自己开始做的,所以界面中显示的是QQ2009)

用用户名字登录。

密码都默认为123

其中,点击界面上的“注册新账号”会出现下图:

在里面填写相应的名字和密码即可注册,当然服务器也要开启相应的端口,如下:

2)界面显示:

将在线好友显示在好友列表中,并实现系统托盘,加入工具栏便于操作。

本界面中左边和右边都是截图所得,这些按钮没有实际功能,只为了模仿QQ。

3)聊天功能:

与好友聊天。

本界面做的时候有点bug,就是聊天窗口中只有一个有个人形象展示,如上,在左边打开的窗口中没有,右边有。

这一个bug有空会改过来的。

4)发送文件:

能发送任一文件,当然文件不能过大,否则可能会出问题。

收到的图片可以正常打开

5)信息提示:

闪动托盘图标提示到来信息,并播放不同音乐来提示。

6)其他:

用户登陆成功,将保存其号码,以便下次登陆时,不必再输入而可以直接选择,显示登陆时间。

服务器端:

写上一个合适的端口后点击开启端口,就可以开启一个端口用来专门接收用户的连接。

当有用户上线进,就会把相应的用户列在列表中。

向各个客户端发布系统消息。

接受来自客户端的各种信息并分别处理。

1)登陆信息:

检查登陆信息是否正确,并向客户端返回登陆信息,如信息正确。

就将在线用户发给该用户,并将该用户的状态发给各在线用户。

同时在服务器端显示出来。

2)聊天信息:

转发给消息指定的用户。

3)申请信息:

自动分配8位用户号码,并保存该用户,同时将信息返回给客户端。

4)用户下线:

将此用户下线消息发给各客户端,并改写用户在服务器端的状态。

 

2.3实验具体实现

1、服务器端:

服务器端启动时,先初始化服务端界面,之后开启一个端口用来监听客户端的连接:

ChatServer.java文件里面:

publicvoidsetUpServer(){

try{

System.out.println(port);

//创建服务端套接字

server=new.ServerSocket(port);

MakeLog.writeLog("成功创建了一个套接字","ChatServer");

//进入一个循环来等待客户端

while(true){

if(server!

=null){

.Socketclient=server.accept();

//开一个线程

ServerThreadnewThread=newServerThread(client);

MakeLog.writeLog("已经创建一个线程连接.客户端地址:

"

+client.getRemoteSocketAddress(),"ChatServer");

listSock.add(client);

//启动线程

newThread.start();

}

}

}catch(Exceptione){

e.printStackTrace();

MakeLog.writeError(e.getMessage(),"ChatServer");

}

}

然后,当有一个客户端连接上来的时候,就开启一个线程分配给该用户,用来管理该用户的连接及一些相关的操作。

(其它知识点与本实验无关,这里就不再写了,下面看客户端)

2、客户端:

客户端一启动时,先构造出登陆界面

,当点击登陆按钮时,先做一下简单的判断,看是否账号或密码为空,当它们都合法的时候就进入下一步:

/**

*对登陆按钮作出回应

*/

publicvoidreact(){

if(null!

=tf_name.getText()||null!

=tf_psw.getText()){

name=tf_name.getText().trim();

psw=tf_psw.getText().trim();

System.out.println("name:

"+name+"psw:

"+psw);

//创建一个连接,连接服务器

connServer(serverIp,port);

ClientMng.manage(client);

//登陆

if(ClientMng.logon(name,psw)){

ClientThreadthreadCl=newClientThread();

threadCl.start();

}else{

javax.swing.JOptionPane.showMessageDialog(jf,"登陆失败!

用户名已登陆或密码或用户名错误!

");

}

}else{

javax.swing.JOptionPane.showMessageDialog(null,

"对不起,用户名和密码不能为空!

!

");

kk=0;

}

jf.dispose();//最后把登陆界面关掉。

}

分析代码。

先用客户端内置的预设的服务器地址和端口进行socket连接信尝试,连接成功时,客户端马上给服务器发送相关的用户名和密码,服务器验证通过的时候会向客户端返回一条确认信息,客户端如果接到该确认信息说明已经登陆成功了,他们就有了一个永久性的连接,直到其中的一方关闭连接为止。

其实在这过程中,还有一些环节:

/**

*登陆用的函数

*@paramname:

登陆用户名

*@parampsw:

登陆密码

*@return:

是否登陆成功,true登陆成功,false登陆失败

*/

publicstaticbooleanlogon(Stringname,Stringpsw){

myName=name;

StringnamePsw;

if(clientSock!

=null){

namePsw=name+"#"+psw;

sendMsg(namePsw,"system");//发送用户名和密码

try{

msg=readPackage();

if(msg.equals("系统说:

对不起,您的用户名可能为空或未注册或已登陆!

")){

//javax.swing.JOptionPane.showMessageDialog(MainClient.getFrame(),

//"对不起,您的用户名可能为空或未注册或已登陆!

");

returnfalse;

}

if(msg.equals("系统说:

登陆失败!

密码错误!

")){

javax.swing.JOptionPane.showMessageDialog(MainClient

.getFrame(),"登陆失败!

密码错误!

");

returnfalse;

}

sendMsg("OK!

","system");

msg=readPackage();

sendMsg("OK!

","system");

//接收服务器发过来的在线用户列表

names=readPackage();

//处理服务器刚发过来的在线用户列表

if(names!

=null&&!

names.equals("")){

String[]s=names.split("说:

");

String[]allName=s[1].split("#");

for(inti=0;i

if(!

allName[i].equals("")&&allName[i]!

=null

&&!

exists(allName[i])){

listUser.add(allName[i]);

}

}

}

//发送一条消息告诉服务器,是否需要它发送分组信息过来

if(needToSendTeamInfo()){

sendMsg("发过来","system");

//接收服务器发过来的分组信息并保存

//msg=readPackage();

SaveFileAfterRecievingTeamInfo();

}else{

sendMsg("不用发","system");

initial();

}

}catch(Exceptionef){

ef.printStackTrace();

}

returntrue;

}

returntrue;

}

当客户端发送了用户名和密码之后,如果收到的信息是:

“对不起,您的用户名可能为空或未注册或已登陆!

”则说明重复登陆,登陆失败。

如果收到的信息是:

“登陆失败!

密码错误!

”则说明是密码错误,当然也有可能是不存在这个用户。

收到的信息如果是其它的情况,则登陆成功,这时,双方还会再各发条“OK”信息来确认双方的连接并协调步伐。

之后,客户端会判断本地是否已经有相关的列表信息,如果有,则会直接读取本地好友列表信息,如果没有的话,会请求服务器发送相关的好友列表。

收到好友列表后,再解析,并构建成一棵树,显示在界面的列表项中。

客户端有一个工具类,里面有一个读取消息并分解消息的方法:

/**

*按协议来读数据,包括XX说:

*@return:

读包结果

*@throwsIOException

*/

publicstaticStringreadPackage()throwsIOException{

//开始读数据

if(dins!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1