Chinaunix首页 | 论坛 | 博客
  • 博客访问: 197007
  • 博文数量: 76
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 490
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-12 16:58
文章分类

全部博文(76)

文章存档

2011年(3)

2010年(52)

2009年(21)

我的朋友

分类:

2009-12-30 16:59:54

一、准备:
服务端:JDK1.5 (这个不用介绍了吧?)
服务端IDE:eclipse ()

客户端:FLEX 3 (Adobe® Flex® 3 是用于构建和维护在所有主要浏览器、桌面和操作系统一致地部署的极具表现力的 Web 应用程序的高效率的开放源码框架。)
客户端IDE:Flex Builder 3 ()

二、缘分的相遇(建立连接):


既然是通信,当然第一步就是要建立连接啦。我们还是用最简单的看代码的方式来开始我们的连接。

==========================================
==服务端代码:Jserver1.java
==========================================

  1. import java.net.*;
  2. import java.io.*;
  3. public class Jserver1 {
  4. public static void main(String[] args) {
  5. ServerSocket server=null;
  6. try{
  7.   server=new ServerSocket(719);//在端口719建立一个服务器套接字对象
  8.   System.out.println("服务端等待");
  9.   while(true){
  10.    System.out.println("等待客户机");
  11.    Socket newSocket=server.accept();//客户端向我们建立的服务器套接字发送连接请求,则向下执行
  12.    System.out.println("已与客户机连接");
  13.   }
  14. }catch(IOException ie)
  15. {
  16.   System.out.println(ie);
  17. }finally{
  18.   try
  19.   {
  20.    if(server!=null) server.close();//关闭服务器套接字。为什么要用finally关键字来做这个事呢?HOHO thinking in java里大师已经说得很清楚了,就是无论出现什么异常,都保证我们的服务端套接字能被关闭。
  21.   }catch(IOException ie){}
  22. }
  23. }
复制代码
嘎嘎,怎么样 注释写得够清楚了吧?OK 让我们编译运行,得到的结果应该如图:
 


OK 再让我们来看看客户端的代码是怎么样的:
==========================================
==客户端代码:Jclient1.mxml
===================================================




  1.   
  2.   import flash.net.Socket;
  3.   private var socket:Socket;
  4.   internal function initApp():void
  5.   {
  6.    socket=new Socket();//创建Socket对象
  7.    socket.connect("localhost",719);  //连接服务器
  8.    socket.addEventListener(Event.CONNECT,connectFun);//监听是否连接上服务器
  9.    socket.addEventListener(Event.CLOSE,closeFun);//监听套接字连接是否关闭
  10.    
  11.   }
  12.   private function connectFun(event:Event):void
  13.   {
  14.    jText.text+="已经成功连接到服务器!\n";
  15.   }

  16.   private function closeFun(event:Event):void
  17.   {
  18.    jText.text+="和服务器断开!\n"
  19.   }
  20.   ]]>


复制代码
界面非常简单啦,其实就是一个TextArea来显示连接的结果而已,运行的结果如下图(注意,服务端也应该在运行!):
 


在as3.0中,所有和网络通信有关的类都位于flash.net包中,这里使用的是Socket类对象。
==========================================
==我们来详细说明一下上面用到的Socket类:
==========================================

Socket对象的常用创建方法有下面2种:

  1. var socket:Socket=new Socket();//例一
复制代码
或者
  1. var socket:Socket=new Socket("localhost",719);//例二.这条语句设置了服务器地址为localhost 端口是719
复制代码
当指定了了服务器地址和端口,Socket对象将自动开始连接服务器。如果不指定,则需要条用connect方法才开始执行连接动作,意思就是,例二的代码和下面的代码是等效的:

  1. var socket:Socket=new Socket();
  2. socket.connect("localhost",719);
复制代码
完成连接动作后,接下来要获取服务端得返回信息。
Socket对象和URLLOADER啊之类的对象都是一样,利用事件机制来处理服务器端的信息,我们只要给Socket对象添加相关的事件监听函数就可以捕捉到服务器端的信息,Socket对象的事件主要有:
1 Event.CLOSE 连接中断事件。
2 Event.CONNECT 连接状态事件,表示已经成功连接了服务器。
3 IOErrorEvent.IO_ERROR 信息传递错误事件,一般是由服务器地址错误引起的。
4 ProgressEvent.SOCKET_DATA 服务器信息事件,当收到服务器的新信息时被触发。

==========================================

哈哈,经过上面的代码,我们的服务端MM和客户端GG终于通过Socket这个缘分宿命的相遇了!接下来会发生什么?我们继续往下看~~

三、第一封情书(客户端发送消息,服务端接受消息)

客户端GG在遇到服务端MM以后,终日变得茶饭不思,在折磨掉了无数根头发以后,客户端GG终于下定决心,要向服务端MM送出第一封情书啦!

既然是客户端GG送出情书,那我们先来看他到底是怎么做的:
==========================================
==客户端代码:Jclient2.mxml
==========================================



  1. import flash.net.Socket;
  2. import flash.utils.ByteArray;

  3. private var socket:Socket=new Socket(); //定义Socket,准备好情书的信封
  4. //初始化程序
  5. internal function initApp():void
  6. {
  7. socket.connect("localhost",719); //连接服务器
  8. socket.addEventListener(Event.CONNECT,funConnect); //监听是否连接
  9. socket.addEventListener(Event.CLOSE,funClose); //监听连接关闭
  10. }
  11. internal function funConnect(event:Event):void
  12. {
  13. myText.text+="连接已建立 \n";
  14. }
  15. internal function funClose(event:Event):void
  16. {
  17. myText.text+="连接已关闭 \n";
  18. }

  19. internal function sendMessage(msg:String):void//发送数据对应按钮click事件
  20. {
  21. var message:ByteArray=new ByteArray();//新建一个ByteArray存放数据
  22. message.writeUTFBytes(msg +"\r\n");//写入数据,writeUTFBytes方法,以utf-8格式传数据避免中文乱码
  23. socket.writeBytes(message);  //写入Socket的缓冲区
  24. socket.flush();  //调用flush方法发送信息
  25. myText.text+=msg+"\r\n";  //在客户端屏幕上输出发送的内容
  26. myInput.text=""; //清空发言框
  27. }
  28. ]]>




复制代码
嘎嘎,情书的做法就上面那面简单,注释已经写得很清楚了,就不多说了。

OK,客户端GG的情书倒是送出去了,我们就来看看服务端MM是怎么接受这封情书的呢?
==========================================
==服务端代码:Jserver2.java
==========================================
  1. import java.net.*;
  2. import java.io.*;
  3. public class Jserver2{
  4. private BufferedReader reader; //负责输入
  5. private ServerSocket server;   //服务器套接字
  6. private Socket socket;      //套接字
  7. public Server2(){}  //缺省构造函数
  8. void startServer()  //启动服务器
  9. {
  10. try
  11. {
  12. server=new ServerSocket(719);    //创建服务器套接字
  13. System.out.println("服务器套接字建立完毕");
  14. while(true)
  15. {
  16.   System.out.println("等待客户端GG");
  17.   socket=server.accept(); //若客户端GG提出连接请求,与socket连接
  18.   System.out.println("完成与客户端的连接");
  19. reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8")); //获取socket输入流,“utf-8”这个编码设置是为了更好显示中文
  20. getMessage();//读取来自客户端的数据,并输出至画面上
  21. }
  22. }catch(Exception e)
  23. {
  24. System.out.println(e);
  25. }finally{
  26. try
  27. {
  28. if(server!=null) server.close();//关闭服务器套接字。
  29. }catch(IOException ie){}
  30. }
  31. }
  32. void getMessage()  //读取来自套接字的信息
  33. {
  34. try
  35. {
  36. while(true)    //循环
  37. {
  38. System.out.println("客户端GG说:"+reader.readLine());
  39. }
  40. }catch(Exception e){}
  41. finally{
  42. System.out.println("客户端中断连接");
  43. try
  44. {
  45. if(reader!=null) reader.close(); //关闭套接字的输入流
  46. if(socket!=null) socket.close();  //关闭套接字
  47. reader=null;
  48. socket=null;
  49. }catch(Exception e){}
  50. }
  51. }
  52. public static void main(String[] args)
  53. {
  54. Server2 server=new Server2();
  55. server.startServer();
  56. }

  57. }
复制代码
哈哈,我们运行来看看,我们的客户端GG的情书能否顺利到达服务端MM的手中呢?
运行结果如下:
 


HOHO 看样子我们的客户端GG的情书,服务端MM是顺利接受到啦。


四、服务端MM的心思(多客户端通信)

在服务端MM收到客户端GG的情书以后,突然发现自己原来还是蛮受欢迎的呢。但是有句俗话说的好,那就是“不能为了一棵树放弃一片森林”。所以服务端MM就想,能不能多接受几个客户端GG的情书呢?(真TMD贱。。。)

OK,既然服务端MM有了这个需求(虽然是很贱的需求),那我们就要来满足她!

来看服务端的代码:
=========================================
==Jserver3.java
=========================================
  1. import java.net.*;
  2. import java.io.*;
  3. import java.util.*;

  4. public class Jserver3 {
  5. private ServerSocket server;
  6. List sManager = new ArrayList();

  7. public Jserver3(){}
  8. void startServer() //运行服务器
  9. {
  10. try
  11. {
  12. server=new ServerSocket(719);
  13. System.out.println("服务器套接字已创建成功!");
  14. while(true)
  15. {
  16. Socket socket=server.accept();
  17. System.out.println("已经与客户端连接");
  18. new J_Thread(socket).start();
  19. sManager.add(socket);
  20. System.out.println("当前客户端连结数:"+sManager.size());
  21. }
  22. }catch(Exception e){}finally
  23. {
  24. try
  25. {
  26. server.close();
  27. }catch(Exception e){}
  28. }
  29. }
  30. public static void main(String[] args) {

  31. Jserver3 server=new Jserver3();
  32. server.startServer();
  33. }
  34. class J_Thread extends Thread  //与客户端进行通信的线程类
  35. {
  36. Socket socket;   //套接字引用变量
  37. private DataInputStream reader;   //套接字输入流
  38. private DataOutputStream writer;  //套接字输出流
  39. J_Thread(Socket socket)   //构造函数
  40. {
  41. this.socket=socket;
  42. }
  43. public void run()
  44. {
  45. try
  46. {

  47. reader=new DataInputStream(socket.getInputStream());//获取套接字的输入流
  48. writer=new DataOutputStream(socket.getOutputStream());//获取套接字的输出流
  49. String msg;
  50. while((msg=reader.readUTF())!=null)//如果收到客户端发来的数据
  51. {
  52. //向客户端发送信息
  53. writer.writeUTF("您的情书已经收到");
  54. writer.flush();
  55. System.out.println("来自客户端:"+msg);

  56. }
  57. }catch(Exception e){}finally
  58. {
  59. try
  60. {
  61. sManager.remove(socket);  //删除套接字
  62. //关闭输入输出流及套接字
  63. if(reader!=null)reader.close();
  64. if(writer!=null)writer.close();
  65. if(socket!=null)socket.close();
  66. reader=null;
  67. writer=null;
  68. socket=null;

  69. System.out.println("客户端离开");//向屏幕输出相关信息
  70. System.out.println("当前客户端的连接数:"+sManager.size());
  71. }catch(Exception e){}
  72. }
  73. }
  74. }

  75. }
复制代码
嘎嘎 在这段代码里,服务端MM为每一个连接的客户端GG分配一个单独的线程,而每一个线程里都持有对应的客户端GG的Socket对象。SO,通过这些多线程,服务端MM就练就了一心N用的功力,可以同时接受N个客户端GG发来的情书了( ,真的太贱了。。。。)

客户端的代码和上面的客户端代码一模一样的,这里就不多说啦!
阅读(758) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~