Java Socket基础(三)

Java Socket基础(一)

Java Socket基础(二)

 
2.3)LinkServer2.java

  1. /** 
  2.  * 开启服务器,长连接各个Socket,主动发送数据 
  3.  * 
  4.  * @author Join 
  5.  */ 
  6. public class LinkServer2 extends Thread { 
  7.   
  8.     /** 服务端口 */ 
  9.     private int port; 
  10.     /** 服务套接字 */ 
  11.     private ServerSocket mServerSocket; 
  12.     /** 服务器监听接口 */ 
  13.     private OnLinkServerListener listener; 
  14.   
  15.     /** 客户端套接字集合 */ 
  16.     private ArrayList<Socket> clientList; 
  17.     /** 客户端的输出流集合 */ 
  18.     private ArrayList<ObjectOutputStream> osList; 
  19.   
  20.     public LinkServer2(int port) { 
  21.        this.port = port; 
  22.        clientList = new ArrayList<Socket>(); 
  23.        osList = new ArrayList<ObjectOutputStream>(); 
  24.     } 
  25.   
  26.     @Override 
  27.     public void run() { 
  28.        try { 
  29.            mServerSocket = new ServerSocket(port); // 创建本地特定端口服务器套接字 
  30.            Socket client = null
  31.            while (true) { 
  32.               client = mServerSocket.accept(); // 接收连接的套接字 
  33.               if (null != listener) { 
  34.                   listener.onClientConnected(client.getInetAddress()); 
  35.               } 
  36.               clientList.add(client); 
  37.               osList.add(new ObjectOutputStream(client.getOutputStream())); // 增加连接的输出流 
  38.            } 
  39.        } catch (BindException e) { // 端口使用中 
  40.            if (null != listener) { 
  41.               listener.onBindException(); 
  42.            } 
  43.        } catch (IOException e) { 
  44.            e.printStackTrace(); 
  45.        } 
  46.   
  47.     } 
  48.   
  49.     /** 发送序列化对象 */ 
  50.     public void sendObj(Object obj) { 
  51.        /* 这个判断非必需的,记得就好 */ 
  52.        if (null != obj && !isSerializable(obj)) 
  53.            throw new IllegalArgumentException( 
  54.                   "Object needs to implement java.io.Serializable!"); 
  55.  
  56.   
  57.        ObjectOutputStream out = null
  58.        for (int i = 0; i < osList.size(); i++) { 
  59.            try { 
  60.               out = osList.get(i); 
  61.               out.writeObject(obj); 
  62.               out.flush(); 
  63.   
  64.               /* 发送null时,表示退出了 */ 
  65.               if (null == obj) { 
  66.                   if (null != listener) { 
  67.                      listener.onExited(clientList.get(i).getInetAddress()); 
  68.                   } 
  69.                   closeSocket(i); // 关闭当前Socket 
  70.                   i--; // 少了个记得减 
  71.               } 
  72.            } catch (SocketException e) { // Connection reset 
  73.               if (null != listener) { 
  74.                   listener.onSocketException(clientList.get(i) 
  75.                          .getInetAddress()); 
  76.               } 
  77.               closeSocket(i); // 关闭当前Socket 
  78.               i--; // 少了个记得减 
  79.            } catch (IOException e) { 
  80.               e.printStackTrace(); 
  81.               closeSocket(i); // 关闭当前Socket 
  82.               i--; // 少了个记得减 
  83.            } 
  84.        } 
  85.     } 
  86.   
  87.     /** 关闭某个Socket */ 
  88.     private void closeSocket(int index) { 
  89.        try { 
  90.            osList.get(index).close(); 
  91.            osList.remove(index); 
  92.            clientList.get(index).close(); 
  93.            clientList.remove(index); 
  94.        } catch (IOException e1) { 
  95.            e1.printStackTrace(); 
  96.        } 
  97.     } 
  98.   
  99.     /** 判断是否序列化 */ 
  100.     private boolean isSerializable(Object obj) { 
  101.        Class<?>[] cls = obj.getClass().getInterfaces(); 
  102.        for (Class<?> clazz : cls) { 
  103.            if (clazz.getName().equals(Serializable.class.getName())) 
  104.               return true
  105.        } 
  106.        return false
  107.     } 
  108.   
  109.     /** 设置服务器监听接口 */ 
  110.     public void setOnLinkServerListener(OnLinkServerListener listener) { 
  111.        this.listener = listener; 
  112.     } 
  113.   
 
二、短连接通信
         客户端请求一次,建立一次Socket,完成后即可关闭。服务端通过accept()等待。
 
1)对象消息
         客户端发送对象,服务端接受对象,很简单的例子。
 
1.1)EasyClient.java

  1. /** 
  2.  * 每次连接服务器发送一个消息 
  3.  *  
  4.  * @author Join 
  5.  */ 
  6. public class EasyClient { 
  7.  
  8.     /** 套接字地址 */ 
  9.     private SocketAddress address; 
  10.     /** 超时时间 */ 
  11.     private int timeout; 
  12.     /** 客户端监听接口 */ 
  13.     private OnClientListener listener; 
  14.  
  15.     public EasyClient(String host, int port, int timeout) { 
  16.         this.address = new InetSocketAddress(host, port); 
  17.         this.timeout = timeout; 
  18.     } 
  19.  
  20.     /** 
  21.      * 发送一个消息 
  22.      *  
  23.      * @param obj 对象消息 
  24.      */ 
  25.     public boolean sendMessage(Object obj) { 
  26.         boolean result = false
  27.         Socket socket = null
  28.         try { 
  29.             socket = new Socket(); 
  30.             socket.connect(address, timeout); 
  31.             if (null != listener) { 
  32.                 listener.onConnected(); 
  33.             } 
  34.             result = sendMessage(socket, obj); 
  35.         } catch (ConnectException e) { // 拒绝连接 
  36.             if (null != listener) { 
  37.                 listener.onConnectException(); 
  38.             } 
  39.         } catch (SocketTimeoutException e) { // 连接超时 
  40.             if (null != listener) { 
  41.                 listener.onTimeoutException(); 
  42.             } 
  43.         } catch (IOException e) { 
  44.             e.printStackTrace(); 
  45.         } finally { 
  46.             try { 
  47.                 if (null != socket) { 
  48.                     socket.close(); // 关闭Socket 
  49.                     socket = null
  50.                 } 
  51.             } catch (IOException e) { 
  52.                 e.printStackTrace(); 
  53.             } 
  54.         } 
  55.         return result; 
  56.     } 
  57.  
  58.     /** 通过Socket发送obj消息 */ 
  59.     private boolean sendMessage(Socket socket, Object obj) { 
  60.         boolean result = false
  61.         ObjectOutputStream os = null
  62.         try { 
  63.             os = new ObjectOutputStream(socket.getOutputStream()); 
  64.             os.writeObject(obj); 
  65.             os.flush(); 
  66.             if (null != listener) { 
  67.                 listener.onMessageSent(obj); 
  68.             } 
  69.             result = true
  70.         } catch (SocketException e) { // Connection reset 
  71.             if (null != listener) { 
  72.                 listener.onSocketException(); 
  73.             } 
  74.         } catch (IOException e) { 
  75.             e.printStackTrace(); 
  76.         } finally { 
  77.             try { 
  78.                 if (null != os) { 
  79.                     os.close(); 
  80.                 } 
  81.             } catch (IOException e) { 
  82.                 e.printStackTrace(); 
  83.             } 
  84.         } 
  85.         return result; 
  86.     } 
  87.  
  88.     /** 设置客户端监听接口 */ 
  89.     public void setOnClientListener(OnClientListener listener) { 
  90.         this.listener = listener; 
  91.     } 
  92.  
 
1.2)EasyServer.java

  1. public class EasyServer extends Thread { 
  2.  
  3.     /** 服务端口 */ 
  4.     private int port; 
  5.     /** 服务套接字 */ 
  6.     private ServerSocket mServerSocket; 
  7.     /** 服务器监听接口 */ 
  8.     private OnServerListener listener; 
  9.  
  10.     public EasyServer(int port) { 
  11.         this.port = port; 
  12.     } 
  13.  
  14.     @Override 
  15.     public void run() { 
  16.         try { 
  17.             mServerSocket = new ServerSocket(port); // 创建本地特定端口服务器套接字 
  18.             Socket socket = null
  19.             while (true) { 
  20.                 socket = mServerSocket.accept(); // 接收连接的套接字 
  21.                 receiveMessage(socket); // 接收socket处理消息 
  22.             } 
  23.         } catch (BindException e) { // 端口使用中 
  24.             if (null != listener) { 
  25.                 listener.onBindException(); 
  26.             } 
  27.         } catch (IOException e) { 
  28.             e.printStackTrace(); 
  29.         } 
  30.     } 
  31.  
  32.     /** 接收处理每个Socket信息 */ 
  33.     private void receiveMessage(Socket socket) { 
  34.         ObjectInputStream is = null
  35.         try { 
  36.             is = new ObjectInputStream(new BufferedInputStream( 
  37.                     socket.getInputStream())); 
  38.             Object obj = is.readObject(); 
  39.             if (null != listener) { 
  40.                 listener.onReceive(socket.getInetAddress(), obj); 
  41.             } 
  42.         } catch (SocketException e) { // Connection reset 
  43.             if (null != listener) { 
  44.                 listener.onSocketException(socket.getInetAddress()); 
  45.             } 
  46.         } catch (IOException e) { 
  47.             e.printStackTrace(); 
  48.         } catch (ClassNotFoundException e) { 
  49.             e.printStackTrace(); 
  50.         } finally { 
  51.             try { 
  52.                 if (null != is) { 
  53.                     is.close(); 
  54.                 } 
  55.                 if (null != socket) { 
  56.                     socket.close(); 
  57.                 } 
  58.             } catch (IOException e) { 
  59.                 e.printStackTrace(); 
  60.             } 
  61.         } 
  62.     } 
  63.  
  64.     /** 设置服务器监听接口 */ 
  65.     public void setOnServerListener(OnServerListener listener) { 
  66.         this.listener = listener; 
  67.     } 
  68.  
 
三、后记
         恩,哦,socket还有个比较常用的是setSoTimeout(),在read()阻塞超时会报SocketTimeoutException,catch住处理即可。
 
         更多的如SSLSocket、NIO的简单例子,可以先Click here!这个整理好的样例工程就不提供了,自己动手^^!
 

         ps:老遇到8W冗余字符,拆着拆着就三个了==!

 

附件:http://down.51cto.com/data/2360758





     本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/893847,如需转载请自行联系原作者




上一篇:CRM WebClient UI里word文档调用web service的问题


下一篇:Android:利用系统服务设置系统音量