2.3)LinkServer2.java
- /**
- * 开启服务器,长连接各个Socket,主动发送数据
- *
- * @author Join
- */
- public class LinkServer2 extends Thread {
- /** 服务端口 */
- private int port;
- /** 服务套接字 */
- private ServerSocket mServerSocket;
- /** 服务器监听接口 */
- private OnLinkServerListener listener;
- /** 客户端套接字集合 */
- private ArrayList<Socket> clientList;
- /** 客户端的输出流集合 */
- private ArrayList<ObjectOutputStream> osList;
- public LinkServer2(int port) {
- this.port = port;
- clientList = new ArrayList<Socket>();
- osList = new ArrayList<ObjectOutputStream>();
- }
- @Override
- public void run() {
- try {
- mServerSocket = new ServerSocket(port); // 创建本地特定端口服务器套接字
- Socket client = null;
- while (true) {
- client = mServerSocket.accept(); // 接收连接的套接字
- if (null != listener) {
- listener.onClientConnected(client.getInetAddress());
- }
- clientList.add(client);
- osList.add(new ObjectOutputStream(client.getOutputStream())); // 增加连接的输出流
- }
- } catch (BindException e) { // 端口使用中
- if (null != listener) {
- listener.onBindException();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /** 发送序列化对象 */
- public void sendObj(Object obj) {
- /* 这个判断非必需的,记得就好 */
- if (null != obj && !isSerializable(obj))
- throw new IllegalArgumentException(
- "Object needs to implement java.io.Serializable!");
- ObjectOutputStream out = null;
- for (int i = 0; i < osList.size(); i++) {
- try {
- out = osList.get(i);
- out.writeObject(obj);
- out.flush();
- /* 发送null时,表示退出了 */
- if (null == obj) {
- if (null != listener) {
- listener.onExited(clientList.get(i).getInetAddress());
- }
- closeSocket(i); // 关闭当前Socket
- i--; // 少了个记得减
- }
- } catch (SocketException e) { // Connection reset
- if (null != listener) {
- listener.onSocketException(clientList.get(i)
- .getInetAddress());
- }
- closeSocket(i); // 关闭当前Socket
- i--; // 少了个记得减
- } catch (IOException e) {
- e.printStackTrace();
- closeSocket(i); // 关闭当前Socket
- i--; // 少了个记得减
- }
- }
- }
- /** 关闭某个Socket */
- private void closeSocket(int index) {
- try {
- osList.get(index).close();
- osList.remove(index);
- clientList.get(index).close();
- clientList.remove(index);
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- }
- /** 判断是否序列化 */
- private boolean isSerializable(Object obj) {
- Class<?>[] cls = obj.getClass().getInterfaces();
- for (Class<?> clazz : cls) {
- if (clazz.getName().equals(Serializable.class.getName()))
- return true;
- }
- return false;
- }
- /** 设置服务器监听接口 */
- public void setOnLinkServerListener(OnLinkServerListener listener) {
- this.listener = listener;
- }
- }
二、短连接通信
客户端请求一次,建立一次Socket,完成后即可关闭。服务端通过accept()等待。
1)对象消息
客户端发送对象,服务端接受对象,很简单的例子。
1.1)EasyClient.java
- /**
- * 每次连接服务器发送一个消息
- *
- * @author Join
- */
- public class EasyClient {
- /** 套接字地址 */
- private SocketAddress address;
- /** 超时时间 */
- private int timeout;
- /** 客户端监听接口 */
- private OnClientListener listener;
- public EasyClient(String host, int port, int timeout) {
- this.address = new InetSocketAddress(host, port);
- this.timeout = timeout;
- }
- /**
- * 发送一个消息
- *
- * @param obj 对象消息
- */
- public boolean sendMessage(Object obj) {
- boolean result = false;
- Socket socket = null;
- try {
- socket = new Socket();
- socket.connect(address, timeout);
- if (null != listener) {
- listener.onConnected();
- }
- result = sendMessage(socket, obj);
- } catch (ConnectException e) { // 拒绝连接
- if (null != listener) {
- listener.onConnectException();
- }
- } catch (SocketTimeoutException e) { // 连接超时
- if (null != listener) {
- listener.onTimeoutException();
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (null != socket) {
- socket.close(); // 关闭Socket
- socket = null;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return result;
- }
- /** 通过Socket发送obj消息 */
- private boolean sendMessage(Socket socket, Object obj) {
- boolean result = false;
- ObjectOutputStream os = null;
- try {
- os = new ObjectOutputStream(socket.getOutputStream());
- os.writeObject(obj);
- os.flush();
- if (null != listener) {
- listener.onMessageSent(obj);
- }
- result = true;
- } catch (SocketException e) { // Connection reset
- if (null != listener) {
- listener.onSocketException();
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (null != os) {
- os.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return result;
- }
- /** 设置客户端监听接口 */
- public void setOnClientListener(OnClientListener listener) {
- this.listener = listener;
- }
- }
1.2)EasyServer.java
- public class EasyServer extends Thread {
- /** 服务端口 */
- private int port;
- /** 服务套接字 */
- private ServerSocket mServerSocket;
- /** 服务器监听接口 */
- private OnServerListener listener;
- public EasyServer(int port) {
- this.port = port;
- }
- @Override
- public void run() {
- try {
- mServerSocket = new ServerSocket(port); // 创建本地特定端口服务器套接字
- Socket socket = null;
- while (true) {
- socket = mServerSocket.accept(); // 接收连接的套接字
- receiveMessage(socket); // 接收socket处理消息
- }
- } catch (BindException e) { // 端口使用中
- if (null != listener) {
- listener.onBindException();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /** 接收处理每个Socket信息 */
- private void receiveMessage(Socket socket) {
- ObjectInputStream is = null;
- try {
- is = new ObjectInputStream(new BufferedInputStream(
- socket.getInputStream()));
- Object obj = is.readObject();
- if (null != listener) {
- listener.onReceive(socket.getInetAddress(), obj);
- }
- } catch (SocketException e) { // Connection reset
- if (null != listener) {
- listener.onSocketException(socket.getInetAddress());
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } finally {
- try {
- if (null != is) {
- is.close();
- }
- if (null != socket) {
- socket.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /** 设置服务器监听接口 */
- public void setOnServerListener(OnServerListener listener) {
- this.listener = listener;
- }
- }
三、后记
恩,哦,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,如需转载请自行联系原作者