长沙理工大学网络系统课程设计Word格式.docx

上传人:b****5 文档编号:17509189 上传时间:2022-12-06 格式:DOCX 页数:28 大小:752.58KB
下载 相关 举报
长沙理工大学网络系统课程设计Word格式.docx_第1页
第1页 / 共28页
长沙理工大学网络系统课程设计Word格式.docx_第2页
第2页 / 共28页
长沙理工大学网络系统课程设计Word格式.docx_第3页
第3页 / 共28页
长沙理工大学网络系统课程设计Word格式.docx_第4页
第4页 / 共28页
长沙理工大学网络系统课程设计Word格式.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

长沙理工大学网络系统课程设计Word格式.docx

《长沙理工大学网络系统课程设计Word格式.docx》由会员分享,可在线阅读,更多相关《长沙理工大学网络系统课程设计Word格式.docx(28页珍藏版)》请在冰豆网上搜索。

长沙理工大学网络系统课程设计Word格式.docx

对于五子棋与围棋的关系有两种说法,一说早于围棋,早在“尧造围棋”之前,民间就已有五子棋游戏;

一说源于围棋,是围棋发展的一个分支。

在中国的文化里,倍受人们的青睐。

古代的五子棋的棋具与围棋相同,纵横各十七道。

五子棋大约随围棋一起在我国南北朝时先后传入朝鲜、日本等地。

Java是一种应用于分布式网络环境中的程序设计语言,由Sun微系统公司开发。

Java语言广为人知,得益于Internet的迅猛发展。

特别是Applet在Web上的应用吸引了更多人们对Java语言的关注,人们开始了解并使用这种神奇的语言。

1.1课程设计预期

(1)实现服务器端以及客户端的功能。

(2)游戏界面朴素美观。

(3)棋子样式采用传统样式,黑色和白色。

(4)客户端的信息交流完全通过服务器传递完成。

1.2课程设计内容

本次课程设计主要分为客户机和服务器两部分的设计,其中在服务器端可以创建待机室供其它未处于下棋状态的人们使用,也可以创建另一个房间,供下棋的两个人使用。

我们将通过标记号码来区别待机室与下棋室。

即用0标记待机室,其它房间使用0以上的自然数来标记。

如图1.2.1,客户机向服务器发送消息(a),与客户机连接的线程将收到的消息转发给消息广播者(b)。

然后,消息广播者会负责跟踪具有与客户机1相同的房间号的线程,并将消息传播给它们。

图1.2.1

1.3课程设计过程

1)理论知识学习:

本课程设计主要参考谢希仁编著的《计算机网络(第6版)》[1],语言方面采用的是徐明浩[韩]编著的《Java编程基础,应用与实例》[2]。

理论知识是一切研究设计的基础,所以扎实基础为研究设计的第一步,然后才开始进行设计。

2)分析和撰写文档:

本课程设计的大体分为创建通讯协议,网络五子棋游戏服务器端,网络五子棋游戏客户端三部分的设计。

编写好程序代码,进行编译,发现问题并且解决问题。

3)分析结果并得出结论:

最后一部分则是对编码编译,执行,看是否达到预期效果,若没有达到,则根据运行结果思考今后编程中需要注意的问题,代码格式和规范等。

1.4编程环境

1)软件方面:

测试程序在Windows7下的Myeclipse10.0环境中编写并测试。

2)硬件方面:

测试数据的生成及结果在第4代CPU酷睿i5-4200U、AMDRadeonHD

8670M、4GB内存的微机生成和通过。

3)编程语言:

选用语言为Java。

2总体设计与实现

2.1通信协议

为保证服务器与客户机正常的通信,我们需要确定所交换的信息属于何种类型。

例如,客户机向服务器提出进入某个房间的请求后,服务器必须确认所请求的房间是否允许它进入,然后,发送相应的消息给客户机。

对于消息,我们可以采用“[消息类型]+内容”的形式。

假若想进入第20号房间,那么,它需要向服务器发送消息“[ROOM]20”。

如果第20号房间允许进入,那么,服务器在进行了某些处理后会向客户机传送消息“[ROOM]20”。

相反,若20号房间禁止入内,则服务器将向客户机发送“[FULL]”消息。

游戏中的消息类型见表2.1.1和表2.1.2。

表2.1.1客户机的消息

客户机端消息类型

说明

[NAME]小明

发送玩家的名字

[ROOM]20

请求进入20号房间

[MSG]字符串

发送聊天信息

[START]

通知已做好游戏开始的准备

[DROPGAME]

宣布弃权

[STONE]57

通知将妻子置于(5,7位置)

[WIN]

宣布获胜

[STOPGAME]

通知终止游戏

表2.1.2服务器的消息

服务器端消息类型

[EXIT]小明

通告小明退出房间

[ENTER]小明

通告小明进入房间

通知对方已在(5,7)位置放置了棋子

[COLOR]BLACK

通知开始时,通知黑棋已被选中

[COLOR]WHITE

游戏开始时,通知白棋已被选中

通知玩家已经进入20号房间

[FULL]

通知房间都已满员

通知对方已弃权

通告已经获胜

[LOSE]

通知游戏失败

[DISCONNECT]

通知对方已经掉线

[PLAYER]

发送当前房间中的用户名

名字间使用tab键分割

例:

[PLAYER]小明\t小红\t小花

2.2五子棋游戏服务器端

服务器端主要有3个类:

OmokServer类、Omok_Thread类(线程类)、和BManager类

(消息广播者)。

OmokServer类在收到客户机的连接请求后,将创建新的套接字,并使其与客户机连接,然后启动线程,并将线程添加至BManager对象中。

PrivateBManagerbMan==newBManager();

//消息广播者对象

While(true){

Socketsocket=server.accept();

//获取套接字

Omok_Threadot=newOmok_Thread(socket);

//创建线程

ot.start();

//启动线程

bMan.add(ot);

//添加线程

}

Omok_Thread对象不仅可以获取套接字、输入输出流,而且它还提供了有关客户机的信息,例如客户机的名称、房间号、游戏开始与否等。

这是因为我们需要确定消息的来源及要在某个房间传播的消息。

并且,消息广播者也需要参照线程对象的房间号,以便将消息发送至某个房间中。

2.3五子棋客户端

客户端首先要实现五子棋盘(OmokBoard类)。

五子棋盘继承了画布类,它内嵌于框架窗口中,拥有15*15个格子。

为了响应用户的下棋动作,五子棋盘必须能够响应鼠标事件,并且它必须拥有输出流,用以向对手传递当前棋手的下棋信息。

程序中也有多种方法用来实现绘图操作。

然而,程序中最重要的部分就是如何决定胜负。

横、竖或者对角线向上拥有五颗同颜色的棋子时,即为胜利。

看图2.3.1,首先在1、2、3、4号位置各放置一颗黑色棋子。

如果黑方最后一颗棋子放在5号位置,则黑方在横向上五子连珠,黑方胜。

程序的实现:

在放下5号棋子后,首先程序要计算出它左边连在一起的黑色棋子个数。

其左边已放有1、2和3号棋子,且都是连在一起的,所以5号棋子左边相连的黑色棋子有一颗。

然后,再计算5号棋子右边连在一起的黑色棋子个数。

如图,5号棋子右边有4号。

因此,5号棋子左边、右边还有其本身合起来总共五颗黑色棋子,黑方获胜。

图2.3.1

map是一个二元数组,用于保存棋子的位置。

如果在(2,3)位置上有一颗黑色棋子,则向数组元素map[2][3]赋入BLACK(=1);

若为白棋,则将WHITE(=-1)值代入。

并且,如果某个位置没有任何棋子,则向对应的数组元素中赋0值。

map[2][3]=BLACK;

//在(2,3)位置上,放置黑色棋子

map[5][5]=WHITE;

//在(5,5)位置上,放置白色棋子

map[10][10]=0;

//在(10,10)位置上,没有棋子

count()方法用来查找并计算连载一起的棋子的个数。

p为基准坐标,dx、dy分别为表示横向与竖向的变量。

col代表棋子的颜色。

若dx为-1,dy为0,则计算左边连续棋子的个数;

若dx为1,dy为1,则计算左下到右上对角线方向上连续棋子的个数。

dx与dy只取-1、0、1三个值之一。

下面是count()方法的代码。

privateintconut(pointp,intdx,intdy,intcol){

inti=0;

for(;

map[p.x+(i+1)*dx][p.y+(i+1)*dy]==col;

i++)

{}

return1;

check()方法会调用count()方法,用来判断是否五子连珠。

其代码如下。

privatebooleancheck(pointp,intcol){

if(count(p,1,0,col)+count(p,-1,0,col)==4)//横向检查

returntrue;

if(count(p,0,1,col)+count(p,0,-1,col)==4)//竖向检查

if(count(p,-1,-1,col)+count(p,1,1,col)==4)//对角线方向检查

if(count(p,1,-1,col)+count(p,-1,1,col)==4)//对角线方向检查

returnfalse;

3.程序的测试

3.1服务器端的建立

在Myeclipse10.0中运行服务器代码,截图如图3.1.1。

图3.1.1

3.2客户机端的运行

在Myeclipse10.0中执行客户机代码,截图如图3.2.1。

右下角显示已经连接到服务器。

图3.2.1

3.3五子棋游戏完整执行

在Myeclipse10.0中完整执行游戏,如图3.3.1

图3.3.1

双方进行下棋,并且在右下方进行了通讯。

4.结束语

Java作为一种分布式和可移植的计算机语言,在网络软件开发上有着特别的优点。

它开发方便、快捷,安全性高,对以往复杂的功能,尤其是网络通信等方面,实现起来简洁明了,在网络编程领域有着巨大的发展潜力。

这次Java课程设计完成了一个网络五子棋的设计和开发。

包括服务器和客户端。

不同的用户使用客户端,利用服务器相连。

实现了用户在Internet上任何地方与别人进行五子对战。

网络五子棋的实现用到了网络套接字和多线程的相关知识。

服务器创建服务器Socket,并处于监听状态。

客户端向服务器发出申请,服务器接受后,利用输入输出流进行通信。

并开始一个线程,处理与这个相连的客户端在游戏过程的数据传输、控制等。

进行五子棋的一个主要算法就是判断输赢。

这里采用计算落下棋子的横、竖及对角线方向的同色棋子的个数来实现。

当个数为5时为胜。

服务器与客户端在通信过程中,双方如何知道发送信息的意义呢?

这里发送的信息采用“[消息类别]+内容“的格式。

服务器和客户端通过分析“消息类别”来采取不同的方法处理发送的数据。

通过这次课程设计,加深了我对Java网络编程和多线程编程方面的了解。

网络五子棋基本实现了网络对战的功能,但只能通过网络,没有实现人机对战的功能。

也没有添加“禁手”规则。

这时是已后要改进的地方。

参考文献

[1]谢希仁计算机网络(第6版).电子工业出版社,2013

[2](韩)徐明浩Java编程基础、应用与实例.人民邮电出版社,2006

[3]王吴迪,赵枫朝Java开发与应用.电子工业出版社,2006

附录程序代码

OmokServer.java

import.*;

importjava.io.*;

importjava.util.*;

publicclassOmokServer{

privateServerSocketserver;

privateBManagerbMan=newBManager();

privateRandomrnd=newRandom();

publicOmokServer(){}

voidstartServer(){

try{

server=newServerSocket(7777);

System.out.println("

服务器套接字已被创建."

);

while(true){

Socketsocket=server.accept();

Omok_Threadot=newOmok_Thread(socket);

ot.start();

bMan.add(ot);

连接数:

"

+bMan.size());

}

}catch(Exceptione){

System.out.println(e);

publicstaticvoidmain(String[]args){

OmokServerserver=newOmokServer();

server.startServer();

classOmok_ThreadextendsThread{

privateintroomNumber=-1;

privateStringuserName=null;

privateSocketsocket;

privatebooleanready=false;

privateBufferedReaderreader;

privatePrintWriterwriter;

Omok_Thread(Socketsocket){

this.socket=socket;

SocketgetSocket(){

returnsocket;

intgetRoomNumber(){

returnroomNumber;

StringgetUserName(){

returnuserName;

booleanisReady(){

returnready;

publicvoidrun(){

reader=newBufferedReader(newInputStreamReader(socket.getInputStream()));

writer=newPrintWriter(socket.getOutputStream(),true);

Stringmsg;

while((msg=reader.readLine())!

=null){

if(msg.startsWith("

[NAME]"

)){

userName=msg.substring(6);

}

elseif(msg.startsWith("

[ROOM]"

introomNum=Integer.parseInt(msg.substring(6));

if(!

bMan.isFull(roomNum)){

if(roomNumber!

=-1)

bMan.sendToOthers(this,"

[EXIT]"

+userName);

roomNumber=roomNum;

writer.println(msg);

writer.println(bMan.getNamesInRoom(roomNumber));

[ENTER]"

elsewriter.println("

[FULL]"

elseif(roomNumber>

=1&

&

msg.startsWith("

[STONE]"

))

bMan.sendToOthers(this,msg);

[MSG]"

bMan.sendToRoom(roomNumber,"

["

+userName+"

]:

+msg.substring(5));

[START]"

ready=true;

if(bMan.isReady(roomNumber)){

inta=rnd.nextInt

(2);

if(a==0){

writer.println("

[COLOR]BLACK"

[COLOR]WHITE"

else{

[STOPGAME]"

ready=false;

[DROPGAME]"

[WIN]"

[LOSE]"

}finally{

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+"

已断线."

连接人数:

bMan.sendToRoom(roomNumber,"

[DISCONNECT]"

}catch(Exceptione){}

classBManagerextendsVector{

BManager(){}

voidadd(Omok_Threadot){

super.add(ot);

voidremove(Omok_Threadot){

super.remove(ot);

Omok_ThreadgetOT(inti){

return(Omok_Thread)elementAt(i);

SocketgetSocket(inti){

returngetOT(i).getSocket();

voidsendTo(inti,Stringmsg){

PrintWriterpw=newPrintWriter(getSocket(i).getOutputStream(),true);

pw.println(msg);

}catch(Exceptione){}

intgetRoomNumber(inti){

returngetOT(i).getRoomNumber();

synchronizedbooleanisFull(introomNum){

if(roomNum==0)returnfalse;

intcount=0;

for(inti=0;

i<

size();

if(roomNum==getRoomNumber(i))count++;

if(count>

=2)returntrue;

voidsendToRoom(introomNum,Stringmsg){

if(roomNum==getRoomNumber(i))

sendTo(i,msg);

voidsendToOthers(Omok_Threadot,Stringmsg){

if(getRoomNumber(i)==ot.getRoomNumber()&

getOT(i)!

=ot)

synchronizedbooleanisReady(introomNum){

if(roomNum

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

当前位置:首页 > 职业教育 > 职高对口

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

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