Download presentation
Presentation is loading. Please wait.
Published by墩佃 邓 Modified 8年之前
1
Java 游戏开发 学习情境 7 :网络对弈程序 08 游戏 3-2
2
目标与任务 目标: ◦ 为游戏添加网络通信功能和游戏逻辑 , 利用 Socket 进行网络通信, C/S 架构服 务器端和客户端编写, B/S 架构实现。 任务: ◦ 开发网络对弈程序
3
目标程序 完成项目开发:程序运行时,有两个 客户端通过网络进行对奕。
4
学习过程 步骤一:先完成简单的 C/S 架构 步骤二:再完成第二个例,实现一个服务器与 多个客户端通信 步骤三:再为服务器端创建线程,实现多线程 服务器 步骤四:最后加入分析两客户端通信的信息, 实现游戏规则的代码
5
网络通信基础 网络通信就是通过某种方法让一台计算机与其它 计算机交换数据。 通信就是给其它计算机传数据,或者接收其它计 算机发来的数据。 对网络的任何形式的访问最后都归结为从网卡接 收数据或向网卡传送数据。 网络通信解决两个问题: ( 1 )如何识别不同的计算机。 ( 2 )如何传送数据。
6
网络通信问题 网络中的两台计算机靠协议进行通信 网络中用 IP 标识不同的通信实体 IP : 219.123.14.110 IP : 116.123.214.108 http ftp mail
7
网络协议 在两台电脑间传送数据时,传送或接收数据的先 后顺序,数据的格式等内容的约定构成通信的协 议。 Internet 网的数据传送有很多协议,如 TCP/IP , UDP , FTP 等,协议不同,具体到网络通信程序, 接收和发送数据部分的代码会有不同。 本次的例子都是采用 TCP/IP 协议。
8
用 IP 识别网络中的计算机 网络上不同的计算机用 IP 来标识。 实际上一个 IP 对应一张网卡。 如果一台电脑上有多张网卡,那么就需要多个 IP 来标识每一张网卡。 每个网卡有多个端口,供应用程序采用不同的通 信协议传输数据。 每种协议都采用不同的端口号,端口号可以设置, 如设置某网卡用 8080 号端口进行 TCP/IP 协议方 式的数据传输。
9
网络程序的架构 一般网络上程序都是一个服务器,一个客户端,这种 程序的总体结构叫架构,如上图所示这种总体结构叫 C/S 架构(即客户 / 服务器)架构。 C/S 架构中,提出数据访问要求的程序叫客户端,被 提出数据访问要求的程序叫服务器端。 一个客户端可能是一台配置很高的电脑,一个服务器 端可能只是一台普通电脑。 客户端和服务器端可以是同一台电脑。 C SC S C S
10
网络编程工具 网络很普遍,所以,几乎所有的编程语言都提供 网络编程的组件。 Java 提供 Socket 组件供网络编程使用。 Socket 是一个类。 在用 Java 进行网络编程时,只需使用 Socket 的 有关方法 ,按照一定步骤编写出接收数据,处理 数据,或处理数据,发送数据的代码即可。
11
Java Socket 编程 事实上网络编程简单的理解就是两台计算机相 互通讯数据而已,对于程序员而言,去掌握一 种编程接口并使用一种编程模型相对就会显得 简单的多了, Java SDK 提供一些相对简单的 API 来完成这些工作。 Socket 就是其中之一, 对于 Java 而言,这些 API 存在于 java.net 这个 包里面,因此只要导入这个包就可以准备网络 编程了。
12
Socket 编程步骤 Java 提供了对 TCP 套接字的良好的支持,有两种套接字 类: java.net.Socket ; java.net.ServerSocket ; 当编写连接到已有服务的客户端软件的时候使用 Socket 类。当编写绑定到本地端口以提供服务的服务器软件的时 候使用 ServerSocket 类。这是与 DatagramSocket 的 UDP 工作方式不同的地方 -- 在 TCP 中,连接服务器地和从 客户端接收数据的函数被分为两个独立的类。
13
Socket 编程步骤 Java 中 Socket 可以理解为客户端或者服务器端的一个特 殊的对象,这个对象有两个关键的方法,一个是 getInputStream 方法,另一个是 getOutputStream 方法。 getInputStream 方法可以得到一个输入流,客户端的 Socket 对象上的 getInputStream 方法得到的输入流其实就 是从服务器端发回的数据流。 GetOutputStream 方法得到 一个输出流,客户端 Socket 对象上的 getOutputStream 方 法返回的输出流就是将要发送到服务器端的数据流,(其 实是一个缓冲区,暂时存储将要发送过去的数据)。
14
Socket 编程步骤 要完成这个工作,需要完成三个部分的工作,以 下依次说明: 1 、建立服务器类 2 、建立客户端代码 3 、建立用户界面
15
1 、建立服务器类 创建服务器对象 : ServerSocket server = new ServerSocket(9998) 建立一个 Socket 连接 : Socket incoming = server.accept() 输入流和输出流 : BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter(incoming.getOutputStream(),true); 随后,就可以使用 in.readLine() 方法得到客户端的输入,也可以 使用 out.println() 方法向客户端发送数据。 关闭这两个数据流 out.close(); in.close();
16
2 、建立客户端代码 创建一个 Socket 对象 :Socket socket = new Socket("168.160.12.42",9998); 数据的输入和输出 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true);
17
项目核心:简单的 C/S 架构 客户机 / 服务器的典型通信过程: 1 、服务器监听相应端口的输入; 2 、客户机发出一个请求; 3 、服务器接收到此请求; 4 、服务器处理这个请求,并把结果返回 给客户机; 5 、重复上述过程,直至完成一次会话过 程。
18
项目核心:简单的 C/S 架构 服务方: import java.io.*; import java.net.*; public class MyServer { public static void main(String[] args) throws IOException{ ServerSocket server=new ServerSocket(5678); Socket client=server.accept(); BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out=new PrintWriter(client.getOutputStream()); while(true){ String str=in.readLine(); System.out.println(str); out.println("has receive...."); out.flush(); if(str.equals("end")) break; } client.close(); } }
19
项目核心:简单的 C/S 架构 这个程序的主要目的在于服务器不断接收客户 机所写入的信息只到,客户机发送 "End" 字符 串就退出程序,并且服务器也会做出 "Receive" 为回应,告知客户机已接收到消息。
20
项目核心:简单的 C/S 架构 客户机代码 : import java.net.*; import java.io.*; public class Client { static Socket server; public static void main(String[] args)throws Exception{ server=new Socket(InetAddress.getLocalHost(),5678); BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream())); PrintWriter out=new PrintWriter(server.getOutputStream()); BufferedReader wt=new BufferedReader(new InputStreamReader(System.in)); while(true){ String str=wt.readLine(); out.println(str); out.flush(); if(str.equals("end")){ break; } System.out.println(in.readLine()); } server.close(); } }
21
项目核心:简单的 C/S 架构 客户机代码则是接受客户键盘输入, 并把该信 息输出,然后输出 "End" 用来做退出标识。 这个程序只是简单的两台计算机之间的通 讯,如果是多个客户同时访问一个服务器呢? 你可以试着再运行一个客户端,结果是会抛出 异常的。那么多个客户端如何实现呢 ?
22
一对一的 C/S 一个 Server 一个 Client 一对多的 C/S 一个 server 多个 Client C SC S C S C C
23
功能扩展:将客户端改成 Java Applet ,即 B/S 架构,为客户端设计符合需求的 GUI 。 网络通信模型 B/S 架构:如果客户端是浏览器, 则通信程序的架构叫浏览器 / 服务器架构(即 Browser/Server 架构,简称 B/S 架构)。客户 端是通用的浏览器,省掉了客户端升级的麻烦。 B S B B
24
功能扩展:将服务器端改进为 多线程服务器 一个服务器为多个客户端服务 其实, 简单的分析一下,就可以看出客户和服 务通讯的主要通道就是 Socket 本身,而服务器 通过 accept 方法就是同意和客户建立通讯. 这 样当客户建立 Socket 的同时。服务器也会使用 这一根连线来先后通讯,那么既然如此只要我 们存在多条连线就可以了。那么我们的程序可 以变为如下 :
25
功能扩展:将服务器端改进为 多线程服务器 改进为多线程服务器: try { file:// 建立服务器 ServerSocket server = new ServerSocket(9998); int i=1; for(;;) { Socket incoming = server.accept(); new ServerThread(incoming,i).start(); i++; } }catch (IOException ex){ ex.printStackTrace(); }
26
功能扩展:将服务器端改进为 多线程服务器 这里仅仅只是加了一个外层的 While 循环,这 个循环的目的就是当一个客户进来就为它分配 一个 Socket 直到这个客户完成一次和服务器的 交互,这里也就是接受到客户的 "End" 消息. 那 么现在就实现了多客户之间的交互了。
27
功能扩展:将服务器端改进为 多线程服务器 但是. 问题又来了,这样做虽然解决了多客户, 可是是排队执行的。也就是说当一个客户和服 务器完成一次通讯之后下一个客户才可以进来 和服务器交互,无法做到同时服务,那么要如 何才能同时达到既能相互之间交流又能同时交 流呢?很显然这是一个并行执行的问题了。所 以线程是最好的解决方案。
28
功能扩展:将服务器端改进为 多线程服务器 那么下面的问题是如何使用线程. 首先要做的 事情是创建线程并使得其可以和网络连线取得 联系。然后由线程来执行刚才的操作,要创建 线程要么直接继承 Thread 要么实现 Runnable 接口,要建立和 Socket 的联系只要传递引用就 可以了. 而要执行线程就必须重写 run 方法,而 run 方法所做的事情就是刚才单线程版本 main 所做的事情,因此我们的程序变成了 multiThread.java
29
应用升级:网络对奕游戏 本程序实现的是基于 B/S 模式的网络对奕游戏, 实现了多线程编程,实现多客户对奕。并且实 现了服务器端管理客户端的功能,包括客户端 和服务器端。 实现功能: · 用户上线 · 包括新用户上线和已使用过该系统 的用户上线 · 每位在线的用户将会收到该用户上线的通知
30
应用升级:网络对奕游戏 该用户会收到所有已在线的用户的信息 · 朋友 下线 服务器端删除该用户信息 · 每位在线的用户将 会收到该用户下线的通知, 同时删除改用户的信息 · 聊天终止,文件传输 终止 · 修改用户名字 · 用户可以在对应的文本框内直接修改名称
31
应用升级:网络对奕游戏 用户可以在保存的 Myinfo.txt 中直接修改名称 聊天功能: · 公聊:所有在线的用户都可以看到你的发言 · 私聊:能和所有以在线的用户进行私聊,其他 用户看不到私聊对象之间的聊天 · 文件传输 · 能给所有的已在线用户发送文 件(先打开私聊窗口) 网络对弈功能。 实现棋局逻辑设计,实现游戏逻辑程序设计。
32
应用升级:网络对奕游戏 源代码: 客户端 TicTacToeClient.java 服务器端 TicTacToeServer.java
Similar presentations