· [Java论坛][安全论坛][数据库论坛][操作系统论坛]
· [专题] IBM Rational高峰论坛 Windows 7十大功能
· [专题] 史上就危险7月 微软 BizSpark 计划介绍
· [IT技术周刊][IT资源下载专区][病毒求助专区]
· [热点] 我也能做CTO_赛迪连载 赛迪七夕特别行动
· [热点] Chrome 4.0采用V8引擎 Java开发编程规范

C/S环境下的Java应用程序运行过程讲解

发布时间:2007.06.05 05:35     来源:赛迪网技术社区    作者:dxaw

客户机/服务器在分布处理过程中,使用基于连接的网络通信模式。该通信模式首先在客户机和服务器之间定义一套通信协议,并创建一Socket类,利用这个类建立一条可靠的链接;然后,客户机/服务器再在这条链接上可靠地传输数据。客户机发出请求,服务器监听来自客户机的请求,并为客户机提供响应服务。这就是典型的"请求--应答" 模式。下面是客户机/服务器的一个典型运作过程:

1、服务器监听相应端口的输入;

2、客户机发出一个请求;

3、服务器接收到此请求;

4、服务器处理这个请求,并把结果返回给客户机;

5、重复上述过程,直至完成一次会话过程。

按照以上过程,我们使用Java语言编写一个分别针对服务器和客户机的应用程序(Application)。该程序在服务器上时,程序负责监听客户机请求,为每个客户机请求建立Socket

连接,从而为客户机提供服务。本程序提供的服务为:读取来自客户机的一行文本,反转该文本,并把它发回给客户机。

通过该程序实例我们看到,使用Java语言设计C/S程序时需要注意以下几点:

(1)、 服务器应使用ServerSocket

类来处理客户机的连接请求。当客户机连接到服务器所监听的端口时,ServerSocket将分配一新的Socket

对象。这个新的Socket 对象将连接到一些新端口,负责处理与之相对应客户机的通信。然后,服务器继续监听ServerSocket,处理新的客户机连接。

Socket 和ServerSocket 是Java网络类库提供的两个类。

(2)、服务器使用了多线程机制。Server对象本身就是一个线程,它的run()方法是一个无限循环,用以监听来自客户机的连接。每当有一个新的客户机连接时,ServerSocket就会创建一个新的Socket类实例,同时服务器也将创建一新线程,即一个Connection 对象,以处理基于Socket 的通信。与客户机的所有通信均由这个Connection 对象处理。Connection的构造函数将初始化基于Socket 对象的通信流,并启动线程的运行。与客户机的通信以及服务的提供,均由Connection对象处理。

(3)、客户机首先创建一Socket对象,用以与服务器通信。之后需创建两个对象:DataInputStream

和PrintStream,前者用以从Socket 的InputStream

输入流中读取数据,后者则用于往Socket的OutputStream

中写数据。最后,客户机程序从标准输入(如:控制台)中读取数据,并把这些数据写到服务器,在从服务器读取应答消息,然后把这些应答消息写到准输出。

实例:

// Server.java
      import java.io.*;
      import java.net.*;
      public class Server extends Thread
      {
          public final static int Default_Port=6543;
          protectd int port;
          protectd ServerSockt listen_socket;
      // 定义出错例程:如果出现异常错误,退出程序。
      Public static void fail(Exception e, String msg)
      {
          System.err.println(msg   ": "   e);
          System.exit(1);
      }
      // 定义并启动服务器的Socket 
      例程,监听客户机的连接请求。
      public Server(int port)
      {
      if(port == 0) port = Default_Port;
      this.port = port;
      try
      {
      listen_socket = new ServerSocket(port);
      }
      catch(IOException e) fail(e, "Exception creating server 
      socket");
      System.out.println("Server: listening on port"   port);
      This.start();
      }
      /* 
      下面为服务器监听线程的主程序。该线程一直循环执行,监听并接受客户机发出的连接
      请求。对每一个连接,均产生一个连接对象与之对应,通过Socket 
      通道进行通信。*/
      public void run()
      {
      try
          {
      while(true)
      {
          Socket client_socket = listen_socket.accept();
          Connection c = new Connection(client_socket);
                  }
      }
      catch(IOException e) fail(e,"Exception while listening for 
      connections")
      }
      // 启动服务器主程序
      public static void main(String args[])
      {
          int port = 0;
          if (args.length == 1)
          {
          try port = Integer.parseInt(args[0]);
          catch(NumberFormatException e) port = 0;
      }
      new Server(port);
      }                       
      // End of the main
      }                   // End of 
      Server class
      //以下定义了Connection 
      类,它是用来处理与客户机的所有通信的线程。
      class Connection extends Thread
      {
      protected Socket client;
          protected DataInputStream in;
              protected PrintStream out;
      // 初始化通信流并启动线程
      public Connection(Socket client_socket)
      {
              client = client_socket;
          try
          {
           in = new DataInputStream(client.getinputStream());
           out = new PrintStream(client.getOutputStream());
      }
      catch(IOException e)
        {
          try client.close();
              catch(IOException e2);
          System.err.println("Exception while getting socket 
      streram: "   e);
         Return;
        }
       this.start;
      }                   // End of 
      Connection method
      // 
      服务例程:读出一行文本;反转文本;返回文本。
      public void run()
      {
              String line;
          StringBuffer revline;
      int len;
          try
      {
              for(;;)
      {
                  // Read a line
                      line = in.readline();
                          if(line 
      == null) break;
              // Reverse the line
                      len = line.length();
                      revline = new 
      StringBuffer(len);
              for(int i = len-1; i >=0; i--)
              revline.insert(len-1-I;line.charAt(i));
                 // Write out the reverse line
              out.println(revline);
                  }
      catch(IOException e);
      finally try client.close();
      catch(IOException e2);
      }
      // End of run method
      }
      // End of Connection class
      3、编写客户机类Java 程序
      // Client.java
      import java.io.*;
      import java.net.*;
      public class Client extends
      {
          public static final int Default_Port = 6543;
      // 定义出错例程
          public static final void usage()
          {
          System.out.println("Usage: Java Client []");
              System.exit(0);
      }
          public static void main(String args[])
      {
          int port = Default_Port;
      Socket s = null;
      // 解析端口参数
      if ((args.length != 1)&&(args.length != 2 )) usage();
      if (args.length == 1)
          port = Default_Port;
      else
      {
          try port = Integer.parseInt(args[1]);
          catch(NumberFormaatException e) usage();
      }
      try{
        // 产生一个Socket 
      ,通过指定的端口与主机通信。
        s = new Socket(args[0], port);
        // 产生用于发出和接收的文本字符流
        DataInputStream sin = new DataInputStream(s.getInputStream());
        PrintStream sout = new DataInputStream(s.getInputStream());
        // 从控制台读入字符流
        DataInputStream in = new DataInputStream(System.in);
         // 返回连接的地址和端口
        ystem.out.println("Connected to" s.getInetAddress() ":" 
      s.getPort());
          String line;
          For(;;)
          {
              // 显示提示符
              System.out.print(" >");
              System.out.flush();
              // 读入控制台输入的一行字符
              line = in.readline();
              if (line == null) break;
              // 将接收的文本行送至服务器
              sout.println(line);
              // 从服务器接收一行字符
              line = sin.readline();
              // Check if connection is closed(i.e. for 
      EOF)
              if(line == null)
              {
               System.out.println("Connection 
      closed by server.");
               Break;
              }
          // 在控制台上显示接收的字符
          System.out.println(line);
        }
       // End of for loop
      }
      / End of try
      catch(IOException e ) System.err.println(e);
      // Always be sure to close the socket
      finally
      {
          try if(s != null) s.close();
          catch(IOException e2);
      }
      }                       
      // End of main
      }               // End of Client

(责任编辑:龚勋)


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· Java桌面应用程序设计新贵:SWT的简介 (06-04) · 业界动态 Java标准迎挑战 未来由谁主宰 (06-04)
· Java技巧:Java向Web站点发送POST请求 (06-04) · 使用Session机制一些常见的问题 (06-04)
· 实现一个简单的JSP自定义标签开发过程 (06-04) · J2EE基础:Struts框架初学者从这里入门 (06-04)
· Jsp Servlet基础入门学习篇处理Cookie (06-01) · 一篇不错的介绍Java Socket编程的文章 (06-01)
· 功能强大有Java反编译软件(下载) (06-01) · 使用Java实现一个简单的递归算法的实例 (06-01)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
资讯 通信 IT产品 IT技术 信息化
专题:扭亏为盈 联想09年Q2翻番
·专题:Tech·Ed 2009微..
·直播:2009互联网大会..
·迅雷搜狐"互搏" 谁动了..
专题:诺基亚危局已现 或重蹈摩托覆辙
·六股势力角逐4G标准 中..
·专题:联通iPhone并不贵..
·专题:排排坐开商店 三..
商务演示需求分析 多媒体会议室必备投影
·VMware在京隆重举行2009..
·专题:笔记本频道10月热..
·专题:学生机市场 惠普 ..
专题:Tech.Ed 2009微软技术大会
·专题:2009 SYBASE 亚太..
·专题:微软新一代桌面操..
·专题:2009年第3届CSDN..