AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > JAVA编程

Windows CE, PocketPC上的Java编程

51自学网 2015-09-02 http://www.wanshiok.com

 

  分布式的应用程序

  在为各位读着介绍下一个更炫更酷的RMI技术之前笔者先为各位介绍一些分布式应用程序的观念,另外附上一个网络程序与数据库连接的范例架构如下图所示,我们将SocketServer中间安置许多真实的程序逻辑,最后再透过JDBC连接到数据库,如此我们可以将数据库的联机降至最低,至于Client端联机的处理则就需要靠各位撰写程序的技巧啰!!这是常常看到的多层式(N-tier)架构或是分布式的应用程序皆是以此技巧发展出来的笔者所附上的范例程序是属于三层式架构(3-tier)。

  图(三层式)的系统架构

  

  Server端的应用程序

  皆下来的程序满有趣而且也很实用的,希望各位读者会喜欢。下面附上的Server端中具有连接数据库查询及提供Socket服务的Server,各位读者可以在PC端执行。

  //netDBServer.java

  import java.sql.*;

  import java.net.*;

  import java.io.*;

  import java.util.*;

  import org.hsql.util.*;

  public class netDBServer

  {

  String clientMessage;

  ServerSocket sSocket;

  //宣告使用ServerSocket的类别

  Socket csocket;

  //取得Client联机封包的Socket,各为别想太多就是Client端的联机

  public netDBServer()

  {

  try

  {

  sSocket = new ServerSocket(900,200);

  //开启Port 900,并限定Client联机的数量为200,若开启正常则开始等待Client端的联机

  while(true)

  {

  csocket=sSocket.accept();

  Thread t=new MyThreadDB(csocket);

  t.start();

  }

  }

  catch(IOException ioe)

  {

  System.out.println("开启Server异常!!!");

  }

  }

  public static void main(String[] args)

  {

  new netDBServer();

  }

  }

  class MyThreadDB extends Thread

  {

  Socket conn;

  String tempStr;

  DataInputStream dis;

  DataOutputStream dos;

  int ikey;

  String val;

  static Connection con = null;

  String sTestData[]= {

  "create table Place (Code integer,Name varchar(255))",

  "create index iCode on Place (Code)",

  "delete from place",

  "insert into Place values (4900,'Langenthal')",

  "insert into Place values (8000,'Zurich')",

  "insert into Place values (3000,'Berne')",

  "insert into Place values (1200,'Geneva')",

  "insert into Place values (6900,'Lugano')",

  "create table Customer (Nr integer,Name varchar(255),Place integer)",

  "create index iNr on Customer (Nr)",

  "delete from Customer",

  "insert into Customer values (1,'Meier',3000)",

  "insert into Customer values (2,'Mueller',8000)",

  "insert into Customer values (3,'Devaux',1200)",

  "insert into Customer values (4,'Rossi',6900)",

  "insert into Customer values (5,'Rickli',3000)",

  "insert into Customer values (6,'Graf',3000)",

  "insert into Customer values (7,'Mueller',4900)",

  "insert into Customer values (8,'May',1200)",

  "insert into Customer values (9,'Berger',8000)",

  "insert into Customer values (10,'D''Ascoli',6900)",

  "insert into Customer values (11,'Padruz',1200)",

  "insert into Customer values (12,'Hug',4900)"

  };

  static boolean DBCheckInit;

  //建构者

  public MyThreadDB(Socket inSocket)

  {

  conn = inSocket;

  }

  public void run()

  {

  try{

  System.out.println

  ("Server go connect from:"+conn.getInetAddress().getHostName());

  dos = new DataOutputStream(conn.getOutputStream());

  dos.writeUTF("输入查询的资料");

  //get the request conntent

  dis = new DataInputStream(conn.getInputStream());

  tempStr = dis.readUTF();

  //响应一下

  try{

  new org.hsql.jdbcDriver();

  Class.forName("org.hsql.jdbcDriver").newInstance();

  }catch (Exception e){System.out.println(e);}

  try{

  con = DriverManager.getConnection("jdbc:HypersonicSQL:test","sa","");

  Statement select = con.createStatement();

  ResultSet result = select.executeQuery("Select Code,Name FROM Place");

  //初始化数据库

  System.out.println("初始化数据库");

  for(int i=0;i>sTestData.length;i++)

  select.executeQuery(sTestData[i]);

  ResultSet result =

  select.executeQuery("Select Code,Name FROM Place Where Code ="+tempStr);

  System.out.println("Got results:");

  while(result.next()){

  ikey = result.getInt(1);

  if(result.wasNull()){ikey=-1;}

  val = result.getString(2);

  if(result.wasNull()){val=null;}

  System.out.println("Code = "+ikey);

  System.out.println("Name = "+val);

  }

  }catch(Exception e)

  {

  System.out.println(e);

  }/*finally

  {

  if(con!=null){try{con.close();}

  catch(Exception e){e.printStackTrace();}}

  }*/

  //dos.writeUTF("您查询的资料为"+tempStr+"系统正在为您查询中请稍后...");

  dos.writeUTF("您查询的资料为"+val+"系统正在为您查询中请稍后...");

  System.out.println("Server recivews data ="+tempStr);

  conn.close();//断线

  }

  catch(IOException e)

  {System.out.println(e);}

  }

  }

  Client端的应用程序

  Client端的应用程序笔者并没有作窗口程序的设计,只是提供一个雏形给大家使用。

  //Client.java

  import java.net.*;

  import java.io.*;

  public class Client

  {

  public Client()

  {

  try{

  //请配合Server的IP修改

  Socket csocket = new Socket("192.168.0.1",900);

  DataInputStream dis = new DataInputStream(csocket.getInputStream());

  String data = dis.readUTF();

  System.out.println("Client get datafrom server = "+data);

  //write response to server

  DataOutputStream dos = new DataOutputStream(csocket.getOutputStream());

  dos.writeUTF("3000");

  data = "";

  data = dis.readUTF();

  System.out.println("Client get datafrom server = "+data);

  data = dis.readUTF();

  System.out.println("Client get datafrom server = "+data);

  csocket.close();

  }catch(IOException e)

  {

  System.out.println(e);

  }

  }

  public static void main(String[] args)

  {

  new Client();

  }

  }

  编译及执行

  Server端

  javac –classpath %pjeeclasspath%;hsql.jar netDBServer(编译)

  pjava –classpath %pjeeclasspath%;hsql.jar netDBServer(执行)

  注意

  -classpath之后的套件位置请依照情况修改另外别忘记了唷~

  Client端 javac –classpath %pjeeclasspath% Client.java (编译)

  pjava –classpath %pjeeclasspath% Client (执行)

  并且移到我们的PocketPC中执行

  图 Server端激活之后收到Client讯息的画面

  

  图 PDA中的画面

  

  希望这个小架构能够经过各位的修改及调整之后给各位不管是对于研究或是事业上能够帮上一点小小的忙,接着我们就准备进入RMI章节了唷~

  Remote Method Invocation(RMI)

  RMI,是Java所提供的分布式架构的机制,可以用来撰写成是和成是之间的通讯方法,当然你也可以透过Socket来撰写分散的程序(如前一个段落我们所介绍的),但是在使用这些函数需要做相当多繁琐的调整,另外再使用Socket通讯的时候,只能够传递资料,但是是若使用RMI技术不仅可以传递资料也能够传递对象呢!!所以各位只要好好的发挥您的想象力,想想您的程序架构就可以了!

  RMI原理介绍

  我们先看一下下面的联机是意图吧!!在分散室的架构中我们将程序分为Client及Server两端,再使用RMI的机制的时候Client会透过Server的Stub(向是Server的分身)透过RMI的一些运算找到Server的Skeleton,接着Client端就透过控制Server的分身就能够达到使用Server的函示及资源了。

  图 RMI联机示意图

  

  RMI联机过程说明

  如图所示,虽然使用起来RMI感觉是相当的容易的,但是其实他包含了下面几个重要的动作,Client先透过Server的Stub联机的一个注册中心,接着注册中心将Stub和Server的Skeleton联机,然后Client端就可以使用Server端的资源啰。

  图 RMI联机示意图

  

  // CustWork.java 定义Server端提供服务的接口

  import java.rmi.Remote;

  import java.rmi.RemoteException;

  public interface CustWork extends Remote{

  public String getSvrMsg() throws RemoteException;

  }

  // CustWorkImpl.java 这是Server端的服务

  import java.rmi.RemoteException;

  import java.rmi.server.UnicastRemoteObject;

  import java.util.Calendar;

  import java.rmi.server.*;

  public class CustWorkImpl implements CustWork{

  public CustWorkImpl() throws RemoteException{

  UnicastRemoteObject.exportObject(this);

  }

  public String getSvrMsg() throws RemoteException{

  String threadName = Thread.currentThread().getName();

  String curTime = Calendar.getInstance().getTime().toString();

  System.out.println(threadName+" : Aclient connected at "+ curTime);

  return (threadName + " :Message from Server at "+curTime);

  }

  }

  // JSESocketFactory在程序中激活RMI的注册中心及Server服务

  import java.rmi.registry.*;

  import java.rmi.*;

  import java.rmi.RMISecurityManager;

  public class JSESocketFactory

  {

  public static void main(String[] args){

  try {

  //小技巧

  Registry regObj = LocateRegistry.createRegistry(1099);

  CustWorkImpl obj = new CustWorkImpl();

  Naming.rebind("myServer", obj);

  System.out.println

  ("myImpl created and bound in the registry to the name myServer");

  }

  catch (Exception e)

  {

  System.out.println("myImpl.main: an exception occurred:");

  e.printStackTrace();

  }

  }

  }

  //RMIClient.java Client端的程序

  //程序中有关IP的部分请填入Server的IP Address

  import java.rmi.Naming;

  import java.rmi.RemoteException;

  import java.rmi.RMISecurityManager;

  public class RMIClient

  {

  static String servMsg ="";

  public static void main(String[] args)

  {

  try{

  if(System.getSecurityManager() == null)

  System.setSecurityManager(new RMISecurityManager());

  CustWork serRef =

  (CustWork) Naming.lookup("rmi://192.168.0.1:1099/myServer");

  servMsg = serRef.getSvrMsg();

  System.out.println(servMsg);

  }catch(Exception e)

  {

  e.printStackTrace();

  }

  }

  }

  编译及执行程序

  注意!!

  此部分的编译方法为jdk1.1.8的编译方法,若想在计算机中当Server且和J2SE联机的话,你需要设定C:/jdk1.3.1/jre/lib/security 中的 java.policy 一些联机权限的设定,另外产生 stub 及 skeleton 的时候也需要使用rmic –v1.1的参数,因为 Perosnal Java 是参照jdk.1.1.x的规格实作出来的。

  编译程序Server端的Interface及Service

  c:/jdk1.1.8/bin/javac –classpath %pjeeclasspath%;. CustWork.java(1)

  c:/jdk1.1.8/bin/javac –classpath %pjeeclasspath%;. CustWorkImpl.java(2)

  产生Stub及Skeleton

  c:/jdk1.1.8/bin/rmic -classpath %pjeeclasspath%;. CustWorkImpl(3)

  编译Server端程序

  c:/jdk1.1.8/bin/javac -classpath %pjeeclasspath%;. JSESocketFactory.java(4)

  编译Client端程序

  c:/jdk1.1.8/bin/javac -classpath %pjeeclasspath%;. RMIClient.java(5)

  执行程序

  注意您需要开两个DOS窗口来执行这两只程序

  激活RMI Server程序 pjava -classpath %pjeeclasspath%;. JSESocketFactory(1)

  图 RMI Server激活画面

  

  激活RMI Client程序

  pjava -classpath %pjeeclasspath%;. RMIClient

  图 RMI Client激活画面

  

  另外将Client端移植到WinCE中千万别忘了把XXXX_Stub档案也一起移动过去喔。

  结论

  当网络技术,配合无线网络卡,或是其它的产品,相信会是相当有趣的事情喔。

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。
 

上一篇:J2ME游戏开发的高级优化技巧  下一篇:J2ME中使用Canvas制作简单的游戏菜单