事实上网络编程简单的理解就是两台计算机相互通讯数据而已.对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了.Java SDK提供一些相对简单的Api来完成这些工作.Socket就是其中之一.对于Java而言.这些Api存在与java.net 这个包里面.因此只要导入这个包就可以准备网络编程了.
网络编程的基本模型就是客户机到服务器模型.简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置,而另一个则只需要知道这个 固定的位置.并去建立两者之间的联系..然后完成数据的通讯就可以了.这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端.基于这个简单的模 型,就可以进入网络编程啦.
Java对这个模型的支持有很多种Api.而这里我只想介绍有关Socket的编程接口.对于Java而言已经简化了Socket的编程接口.首 先我们来讨论有关提供固定位置的服务方是如何建立的.Java提供了ServerSocket来对其进行支持.事实上当你创建该类的一个实力对象并提供一 个端口资源你就建立了一个固定位置可以让其他计算机来访问你.
ServerSocket server=new ServerSocket(6789);
好了.上面的方法基本可以建立一条连线让两台计算机相互交流了.可是数据是如何传输的呢?事实上I/O操作总是和网络编程息息相关的.因为底层的 网络是继续数据的.除非远程调用,处理问题的核心在执行上.否则数据的交互还是依赖于IO操作的.所以你也必须导入java.io这个包.java的IO 操作也不复杂.它提供了针对于字节流和Unicode的读者和写者,然后也提供了一个缓冲用于数据的读写.
2. new BufferedReader( new InputStreamReader(server.getInputStream()));
3. PrintWriter out=new PrintWriter(server.getOutputStream());
上面两句就是建立缓冲并把原始的字节流转变为Unicode可以操作.而原始的字节流来源于Socket的两个方 法.getInputStream()和getOutputStream()方.分别用来得到输入和输出.那么现在有了基本的模型和基本的操作工具.我们 可以做一个简单的Socket例程了.
服务方:
2. import java.net.*;
3.
4. public class MyServer {
5. public static void main(String[] args) throws IOException{
6. ServerSocket server=new ServerSocket( 5678 );
7. Socket client=server.accept();
8. BufferedReader in=
9. new BufferedReader( new InputStreamReader(client.getInputStream()));
10. PrintWriter out=new PrintWriter(client.getOutputStream());
11. while ( true ){
12. String str=in.readLine();
13. System.out.println(str);
14. out.println("has receive...." );
15. out.flush();
16. if (str.equals( "end" ))
17. break ;
18. }
19. client.close();
20. }
21. }
这个程序的主要目的在于服务器不断接收客户机所写入的信息只到.客户机发送"End"字符串就退出程序.并且服务器也会做出"Receive"为 回应.告知客户机已接收到消息.
客户机代码:
2. import java.io.*;
3.
4. public class Client{
5. static Socket server;
6.
7. public static void main(String[] args) throws Exception{
8. server=new Socket(InetAddress.getLocalHost(), 5678 );
9. BufferedReader in=
10. new BufferedReader( new InputStreamReader(server.getInputStream()));
11. PrintWriter out=new PrintWriter(server.getOutputStream());
12. BufferedReader wt=new BufferedReader( new InputStreamReader(System.in));
13.
14. while ( true ){
15. String str=wt.readLine();
16. out.println(str);
17. out.flush();
18. if (str.equals( "end" )){
19. break ;
20. }
21. System.out.println(in.readLine());
22. }
23. server.close();
24. }
25. }
客户机代码则是接受客户键盘输入,并把该信息输出,然后输出"End"用来做退出标识.
这个程序只是简单的两台计算机之间的通讯.如果是多个客户同时访问一个服务器呢?你可以试着再运行一个客户端,结果是会抛出异常的.那么多个客户 端如何实现呢?
其实,简单的分析一下,就可以看出客户和服务通讯的主要通道就是Socket本身.而服务器通过accept方法就是同意和客户建立通讯.这样当 客户建立Socket的同时.服务器也会使用这一根连线来先后通讯.那么既然如此只要我们存在多条连线就可以了.那么我们的程序可以变为如下:
服务器:
那么下面的问题是如何使用线程.首先要做的事情是创建线程并使得其可以和网络连线取得联系.然后由线程来执行刚才的操作.要创建线程要么直接继承 Thread要么实现Runnable接口,要建立和Socket的联系只要传递引用就可以了.而要执行线程就必须重写run方法.而run方法所做的事 情.就是刚才单线程版本main所做的事情.因此我们的程序变成了这样:
2. import java.io.*;
3.
4. public class MultiUser extends Thread{
5. private Socket client;
6.
7. public MultiUser(Socket c){
8. this .client=c;
9. }
10.
11. public void run(){
12. try {
13. BufferedReader in=
14. new BufferedReader( new InputStreamReader(client.getInputStream()));
15. PrintWriter out=new PrintWriter(client.getOutputStream());
16. //Mutil User but can't parallel
17. while ( true ){
18. String str=in.readLine();
19. System.out.println(str);
20. out.println("has receive...." );
21. out.flush();
22. if (str.equals( "end" ))
23. break ;
24. }
25. client.close();
26. }catch (IOException ex){
27. }finally {
28.
29. }
30. }
31.
32. public static void main(String[] args) throws IOException{
33. ServerSocket server=new ServerSocket( 5678 );
34. while ( true ){
35. //transfer location change Single User or Multi User
36. MultiUser mu=new MultiUser(server.accept());
37. mu.start();
38. }
39. }
40. }