Socket长连接和心跳 博客分类: SocketJ2SE
程序员文章站
2024-03-23 08:48:28
...
LZ一直没有涉猎过长连接,原因不过多解释,懒可能是其中一个理由。突然有一天觉着是个遗憾,于是自己顺手用Socket搞了一个,包括长连接必须有的心跳机制,和对象的传递,当然用到了JAVA序列化,传递的对象必须实现java.io.Serializable接口。
客户端:
package com.feng.test.longconnection; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.ArrayList; /** * * @author songfeng * @version 1.0 * @since 2015-10-14 * @category com.feng.test.longconnection * */ public class Client { private Socket socket; private String ip; private int port; private String id; ObjectOutputStream oos; BufferedReader br; public Client(String ip, int port,String id) { try { this.ip = ip; this.port = port; this.id = id; this.socket = new Socket(ip, port); this.socket.setKeepAlive(true); oos = new ObjectOutputStream(socket.getOutputStream()); br = new BufferedReader(new InputStreamReader(socket.getInputStream())); new Thread(new heartThread()).start(); new Thread(new MsgThread()).start(); } catch (Exception e) { e.printStackTrace(); } } public void sendMsg(Object content) { try { oos.writeObject(content); oos.flush(); } catch (Exception e) { closeSocket(); } } public void closeSocket() { try { socket.close(); oos.close(); br.close(); } catch (IOException e) { e.printStackTrace(); } } class heartThread implements Runnable { @Override public void run() { while(true) { try { Thread.sleep(1000); long time = System.currentTimeMillis(); //System.out.println("client send:" + time); sendMsg("Client" + id + " send:" + time); } catch (InterruptedException e) { e.printStackTrace(); } } } } class MsgThread implements Runnable { @Override public void run() { String str = null; while(true) { try { if(socket.getInputStream().available() > 0) { while((str = br.readLine()) != null) { System.out.println(str); } } } catch (IOException e) { closeSocket(); } } } } public static void main(String[] args) { Client client1 = new Client("127.0.0.1", 55555, "1"); client1.sendMsg(new Pojo("songfeng", 26, new ArrayList<String>())); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Client client2 = new Client("127.0.0.1", 55555, "2"); } }
服务端:
package com.feng.test.longconnection; import java.io.BufferedWriter; import java.io.IOException; import java.io.ObjectInputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * @author songfeng * @version 1.0 * @since 2015-10-14 * @category com.feng.test.longconnection * */ public class Server { private ServerSocket serverSocket; private Socket socket; private int port; static List<Socket> list = new ArrayList<Socket>(); ExecutorService exec; public Server(int port) { try { this.port = port; this.serverSocket = new ServerSocket(port); //线程池管理客户端线程。 exec = Executors.newCachedThreadPool(); while (true) { socket = serverSocket.accept(); list.add(socket); exec.execute(new MsgThread(socket)); } } catch (IOException e) { e.printStackTrace(); } } public void closeSocket() { try { for(Socket s : list) { s.close(); } serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } class MsgThread implements Runnable { private Socket socket; private long lastHeatTime = System.currentTimeMillis(); public MsgThread(Socket socket) { this.socket = socket; } @Override public void run() { ObjectInputStream oin = null; PrintWriter pw = null; String str = null; try { oin = new ObjectInputStream(this.socket.getInputStream()); pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()))); while(true) { if(!socket.isConnected()) { break; } if(socket.getInputStream().available() > 0) { if(System.currentTimeMillis() - lastHeatTime > 5000) { break; } oin.readFields(); Object object = oin.readObject(); if(object instanceof String) { lastHeatTime = System.currentTimeMillis(); long time = System.currentTimeMillis(); pw.println(object + ",Server back:" + time); pw.flush(); } else if(object instanceof Pojo) { pw.println(object + ",Server back:" + ((Pojo)object).getName()); pw.flush(); } } } } catch (Exception e) { e.printStackTrace(); } finally { try { this.socket.close(); list.remove(socket); if(oin != null) { oin.close(); } pw.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void main(String[] args) { Server server = new Server(55555); } }
数据类:
package com.feng.test.longconnection; import java.io.Serializable; import java.util.List; /** * * @author songfeng * @version 1.0 * @since 2015-10-16 * @category com.feng.test.longconnection * */ public class Pojo implements Serializable { /** * 序列化 */ private static final long serialVersionUID = -8868529619983791261L; private String name; private int age; private List<String> likeThing; public Pojo(String name, int age, List<String> likeThing) { super(); this.name = name; this.age = age; this.likeThing = likeThing; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List<String> getLikeThing() { return likeThing; } public void setLikeThing(List<String> likeThing) { this.likeThing = likeThing; } }