随笔 - 303  文章 - 883  trackbacks - 0
<2007年2月>
28293031123
45678910
11121314151617
18192021222324
25262728123
45678910

欢迎光临! 
闲聊 QQ:1074961813

随笔分类(357)

我管理的群

公共blog

  • n维空间
  • Email : java3d@126.com 群 : 12999758

参与管理的论坛

好友的blog

我的其他blog

朋友的网站

搜索

  •  

最新评论

注意:文章中使用的代码没有公用类,如直接使用会报错。若想使用,请自己创建一个PUBLIC,如不知如何创建,建议回头看看JAVA基础部分,本文着重解释原理。

原文作者:于洪斌、马俊光、车雪松

一、java与网络通信

  java是一门适合于分布式计算环境、尤其是Internet程序设计的语言。这不仅仅在于java具有很好的安全性和可移植性,还在于java为Internet编程提供了丰富的网络类库支持。利用这些网络类库,可以轻松编写多种类型的网络通信程序。

 

  TCP/IP协议是当今最流行的协议,也是Internet的基础协议,它代表的是一个协议集合。除传输控制协议TCP和网际协议IP外,TCP/IP协议集还包括其他一些协议,如UDP、FTP、UUCP、ICMP等。

  一般的TCP/IP网络数据通信主要可分为两种不同的通信协议,一种是面向连接的通信协议,这种传输方式在数据传送前必须先在两端建立连接,并且所传送的数据不会丢失,这种方式称为TCP,也称为Stream;另一种方式则是面向非连接方式,即传送数据前,并不必先建立连接,而是将所要传送的数据包成一个分组再传送,使用这种方式,由于没有额外的控制,所以传送的数据可能丢掉。这种方式称为UDP,也称为Datagram。

 

  TCP和UDP都是传输层上的通信协议,也是一般TCP/IP网络上最常使用的通信协议,且各有其用途,如TCP较可靠,所以用在不允许数据丢失的应用上。而UDP则较多应用于处理速度要求较快、数据传输可靠性要求不是很高的应用上,如数据广播。在java中也支持这两种不同的协议,对它们的支持是以类库的形式提供的。通过Socket和ServerSocket类提供了对TCP通信的支持,对于UDP通信则提供了DatagramSocket和DatagramPacket类。它们都包含在java.net类库中。本文中,我们主要探讨TCP通信程序的写法,而UDP通信程序的写法与此类似。

 

   二、通信程序的编写

  在进一步讨论之前,我们先来看看Socket和ServerSocket类的定义(表1)和(表2),关于这两个类的详细内容请见sun公司的JDK或microsoft公司VJ++ 1.1的联机文档。

  

  要使用上面所提供的功能编写网络通信程序,我们可以将要通信的两端分成服务器和客户机端,即建立所谓的客户机/服务器编程模式。在服务器端必须先建立一个ServerSocket对象,然后等待客户机端的访问。而在客户机端,则是建立一个Socket对象直接跟服务器端连接,如果连接建立成功,则服务器端便会产生一个Socket对象,然后我们就可以利用这个Socket对象跟客户机端的Socket对象沟通了。此时在服务器和客户机之间建立了一条可靠连接,客户机和服务器可以在这条连接上可靠的传送数据。客户机发出请求,服务器监听来自客户机的请求,并为客户机提供相应的服务。

 

  基于上述原理,我们编写了简单的客户机/服务器模式的网络通信程序。在服务器端,服务器监听客户机的请求,为每个客户机请求建立Socket连接,从而为客户机提供服务。而所提供的服务只是读取来自客户机的一行文本,并把它发回给客户机。以下是服务器端的通信程序。

  

  1 import  java.io. *
  2
  3    import  java.net. *
  4
  5    class  javaserver  extends  Thread  {        // javaserver开始 
  6
  7    ServerSocket server; 
  8
  9     public  javaserver() 
 10
 11     try  
 12
 13    server  =   new  ServerSocket( 600 );           // 创建服务器端进程ServerSocket端口600
 14    }
 
 15
 16     catch (IOException e) 
 17
 18    System.out.println( " Cannot create Server " );           // 创建失败 
 19
 20    System.exit( 0 ); 
 21
 22    }
 
 23
 24    System.out.println( " Now socket server will Start " );     // 创建成功 
 25
 26     this .start();                                           // 启动ServerSocket 
 27
 28    }
 
 29
 30     public   void  run() 
 31
 32     try  
 33
 34     while  ( true
 35
 36    Socket client  =  server.accept();    // 创建server.accept用于接收客户端信息,同时 
 37
 38    service ss  =   new  service(client);    //  该语句会在每次接收前做一次。把信息放到变量ss中 
 39
 40    }
 
 41
 42    }
 
 43
 44     catch (IOException e) 
 45
 46    System.out.println( " cannot provide service ! " );                 // 出问题,捕获异常 
 47
 48    System.exit( 1 ); 
 49
 50    }
 
 51
 52    }
 
 53
 54     public   static   void  main(String args[]) {       // 主函数,所有函数将在这里被调用 
 55
 56    String data;                                                                   
 57
 58    DataInputStream KeyInput; 
 59
 60     new  javaserver(); 
 61
 62    KeyInput  =   new  DataInputStream(System.in);        // 用于接收客户端数据流 
 63
 64     try  
 65
 66    data  =  KeyInput.readLine();                       // 将收到的数据流写入data变量 
 67
 68    }
 
 69
 70     catch  (IOException e)
 71
 72     return
 73
 74    }
 
 75
 76     if  (data.equals( " quit " )) System.exit( 1 );                   
 77
 78    }
 
 79
 80   }
                                                 // javaserver结束 
 81
 82     class  service  extends  Thread  {                 // 服务器代码重点之处开始 
 83
 84    String data; 
 85
 86    DataInputStream InputS;                    // 接收数据变量 
 87
 88    PrintStream OutputS;                       // 传出数据变量 
 89
 90    Socket Client;     
 91
 92     public  service(Socket ClientSocket) 
 93
 94    Client  =  ClientSocket; 
 95
 96     try  
 97
 98    InputS  =   new  DataInputStream(Client.getInputStream());          
 99          // 接收客户端数据
100         
101    OutputS  =   new  PrintStream (Client.getOutputStream()); 
102          // 向客户端发送数据
103         
104    }
 
105
106     catch  (IOException e)
107
108    System.out.println( " Cannot Connect with Client ! " ); 
109
110     return
111
112    }
 
113
114     this .start();           // 连接成功开始,启动进程 
115
116    }
 
117
118     public   void  run()
119
120     try  
121
122     while  ( true ) {                                 // 创建循环接客户端收数据 
123
124    data  =  InputS.readLine();            
125
126     if  (data  ==   null break ;                       // 判断接收是否完成 
127
128     else  
129
130    OutputS.println(data);                          // 接收完毕的话,输出 
131
132    System.out.println( " From Client:  "   +  data);            // 打印输出 
133
134    }
 
135
136    }
 
137
138    }
 
139
140     catch  (IOException e)
141
142    System.out.println( " Read Data error " ); 
143
144    }
 
145
146     try  
147
148    Client.close();                                      // 关闭与客户端的通信 
149
150    }
 
151
152     catch  (IOException e)
153
154    System.out.println( " Cannot close socket " );                 // 关闭socket 
155
156    }
 
157
158    }
 
159
160   }
 
161
162

 

   在上面的程序中,我们使用了多线程机制。javaserver和service对象本身都是一个线程。javaserver对象首先创建一个ServerSocket对象,并启动线程的运行。它的run()方法用于监听来自客户机的连接。每当有一个新的客户机连接时,ServerSocket就会创建一个新的Socket类实例,并创建一个service对象,同时启动这个对象的线程。每个service对象用于完成与客户机通信、提供服务的任务。这样服务器可以同时与多个客户机连接,同时为多个客户机提供服务。当从标准输入中接收到quit字符串时,服务器退出运行。

  在客户机端,首先创建一个Socket对象,用于与服务器通信。它从标准输入中读取数据,把这些数据传给服务器,再从服务器读取应答信息,然后把这些应答信息写到标准输出。当读取了5行的数据后,客户机程序将退出运行。以下是客户机端的通信程序。

   

 1 import  java.io. *
 2
 3    import  java.net. *
 4
 5    class  javaclient 
 6
 7     public   static   void  main(String args[])
 8
 9    String data;                                         // 与服务器端变量data变量对应 
10
11    Socket Client;                                       // (下同)  
12
13    DataInputStream InputS; 
14
15    DataInputStream KeyS; 
16
17    PrintStream OutputS; 
18
19     int  i  =   0
20
21     try  
22
23    Client  =   new  Socket( " 172.17.3.2 " , 600 );          
24               // 创建客户端Socket进程,发送对象172.17.3.2端口600 
25
26    InputS  =   new  DataInputStream(Client.getInputStream()); 
27                // 接收服务器端数据流 
28
29    OutputS  =   new  PrintStream (Client.getOutputStream()); 
30                // 打印服务器端数据流
31   
32      KeyS  =   new  DataInputStream(System.in); 
33                // 将数据传给本地系统。(想深入了解的请看jdk中的原代码的DataInputStream部分)
34         
35    }
 
36
37     catch (IOException e)
38
39    System.out.println( " Cannot Connect with Server " );          // 出错提示:无法连接到服务器 
40
41     return
42
43    }
 
44
45     try  
46
47     while  (i < 5 ) {               // 创建循环接收数据
48  
49    data  =  KeyS.readLine();            // 将数据读入data中 
50
51    OutputS.println(data);             // 打印数据 
52
53    System.out.println( " ECHO From 
54
55    Server: " + InputS.readLine());         //打印接收到的服务器端数据流 
56
57    i ++
58
59    }
 
60
61    }
 
62
63     catch (IOException e) 
64
65    System.out.println( " IOException  Happened " ); 
66
67    }
 
68
69     try
70
71    System.out.println( " Now will  end this program " ); 
72
73    Client.close();                         // 关闭客户端进程 
74
75    }
 
76
77     catch (IOException e)
78
79    System.out.println( " system cannot close socket " ); 
80              
81    }
 
82
83    }
 
84
85   }
 
86
87

   三、结束语

  通过以上的讨论可知,用java语言编写网络通信程序非常简单,这主要是因为java语言本身就是一门面向网络编程的语言。java提供了多个可用于访问标准Internet协议的类库,从而支持多种Internet协议,包括:FTP,HTTP,NNTP和WWW等,这极大的简化了网络程序设计,可以比较方便的编写出功能完善的应用程序。

  以上只是我们对java语言进行网络通信程序设计的粗浅讨论。利用java语言进行程序设计的好处不一而论,愿我们能起到抛砖引玉的作用。



地震让大伙知道:居安思危,才是生存之道。
posted on 2007-02-24 12:31 小寻 阅读(1084) 评论(0)  编辑  收藏 所属分类: j2se/j2ee/j2menetwork

只有注册用户登录后才能发表评论。


网站导航: