java Socket长链接与消息推送源码与演示

演示视频如下(在服务端输入消息,客户端接收消息) : 

视频链接


服务端代码 MyServer.java 源码如下

  1 import java.io.BufferedReader;
  2 import java.io.IOException;
  3 import java.io.InputStreamReader;
  4 import java.io.OutputStream;
  5 import java.io.PrintWriter;
  6 import java.net.ServerSocket;
  7 import java.net.Socket;
  8 import java.util.HashMap;
  9 import java.util.Iterator;
 10 import java.util.Map;
 11 import java.util.Scanner;
 12 
 13 
 14 public class MyServer {
 15     
 16     private static final Map<String,Socket> connectMap = new HashMap<String,Socket>(); //链接信息
 17     
 18     private static ServerSocket server = null ;
 19     
 20     private static final int PORT = 8888 ;
 21     
 22     //SOCKET 服务线程类
 23     static class ReciveService extends Thread{
 24         
 25         Socket client = null ; 
 26         
 27         private InputStreamReader is = null;
 28         private BufferedReader in = null; 
 29         
 30         public ReciveService(Socket client){
 31             this.client = client ;
 32         }
 33 
 34         public void run() {
 35 
 36             long tid =Thread.currentThread().getId() ;//当前线程ID
 37             try{
 38                 String IP = client.getInetAddress().getHostAddress() ;
 39                 
 40                 System.out.println("已经链接 : "+IP+"["+tid+"]");
 41                 connectMap.put(IP+"#"+tid,client);
 42                 is = new InputStreamReader(client.getInputStream(), "UTF-8");//规定编码
 43                 in = new BufferedReader(is);//接收请求的流
 44                 
 45                 int len = 0;//监听到的字符串长度
 46                 char[] buf = new char[1024];
 47                 while ((len = in.read(buf)) != -1) {
 48                     String s = new String(buf, 0, len);
 49                     s = new String(s.getBytes(),"utf-8");
 50                     System.out.println("-> "+s);
 51                 }
 52             }catch(Exception e){
 53                 e.printStackTrace() ;
 54             }finally{
 55                 //关闭Socket
 56                 if(null != client){
 57                     try {
 58                         client.close() ;
 59                     } catch (IOException e) {
 60                         e.printStackTrace();
 61                     }
 62                 }
 63             }
 64         
 65         }
 66         
 67         
 68     }
 69     
 70     //向客户端发送消息
 71     private static Thread tSend = new Thread(new Runnable(){
 72         Scanner scanner =new Scanner(System.in);
 73         public void run() {
 74             try {
 75                 while (true) {
 76                     String data = scanner.next() ;
 77                     for(Iterator<String> it = connectMap.keySet().iterator();it.hasNext();){
 78                         String key = it.next() ;//IP+线程ID
 79                         Socket client = connectMap.get(key);
 80                         if(null != client && client.isConnected()){
 81                             OutputStream os= client.getOutputStream();            
 82                             PrintWriter pw=new PrintWriter(os);//转化为打印流  
 83                             pw.write(data);  
 84                             pw.flush();//刷新缓存
 85                         }
 86                     }
 87                     Thread.sleep(1000);
 88 //                    System.out.println("...");
 89                 }
 90             } catch (IOException e) {
 91                 e.printStackTrace();
 92             } catch (InterruptedException e) {
 93                 e.printStackTrace();
 94             }
 95         }
 96     });
 97     
 98     
 99     
100     
101     public static void main(String[] args) throws IOException {
102         System.out.println("==============SOCKET 服务端===============");
103         startServer() ;
104     }
105     
106     public static void startServer() throws IOException{
107         server = new ServerSocket(PORT);
108         tSend.start();                                            //启动发送消息线程
109         while(true){
110             try{
111                 Socket client = server.accept() ;                 //主线程获取客户端连接
112                 ReciveService service = new ReciveService(client) ;
113                 service.start();                                //启动接收消息线程
114             }catch(Exception e){
115                 e.printStackTrace() ;
116             }
117         }
118     }
119 }

客户端代码 MyClient.java 源码如下 :

  1 import java.io.IOException;
  2 import java.io.InputStream;
  3 import java.io.OutputStream;
  4 import java.net.Socket;
  5 import java.net.UnknownHostException;
  6 import java.util.Scanner;
  7 
  8 public class MyClient {
  9 
 10     private static final ThreadLocal<Socket> threadConnect = new ThreadLocal<Socket>(); 
 11     
 12     private static final String HOST = "localhost";
 13 
 14     private static final int PORT = 8888;
 15     
 16     private static Socket client;
 17     
 18     private static OutputStream outStr = null;
 19     
 20     private static InputStream inStr = null;
 21     
 22     //数据接收线程
 23     private static Thread tRecv = new Thread(new Runnable(){
 24         public void run() {
 25             try {
 26 //              System.out.println("==============开始接收数据===============");
 27                 while (true) {
 28                     byte[] b = new byte[1024];
 29                     int r = inStr.read(b);
 30                     if(r>-1){
 31                         String str = new String(b,0,r,"utf-8");
 32                         System.out.println( str );
 33                     }
 34                 }
 35             } catch (IOException e) {
 36                 e.printStackTrace();
 37             }
 38         }
 39     });
 40     
 41     //消息发送线程
 42     private static Thread tSend = new Thread(new Runnable(){
 43         Scanner scanner =new Scanner(System.in);
 44         public void run() {
 45 //            System.out.println("=====================开始发送数据==============");
 46             try {
 47                 while (true) {
 48                     String data = scanner.next() ;
 49                     outStr.write(data.getBytes());
 50                 }
 51             } catch (IOException e) {
 52                 e.printStackTrace();
 53             }
 54         }
 55         
 56     });
 57     
 58     //心跳包发送线程
 59     private static Thread tKeep = new Thread(new Runnable(){
 60         public void run() {
 61             try {
 62 //              System.out.println("=====================开始发送心跳包==============");
 63                 while (true) {
 64                     try {
 65                         //http://blog.csdn.net/qq_23167527/article/details/54290726
 66                         Thread.sleep(30000);//心跳频率 30秒 
 67 //                      System.out.println(".");
 68                     } catch (InterruptedException e) {
 69                         e.printStackTrace();
 70                     }
 71                   //发送一个心跳数据包
 72                     outStr.write(new byte[]{});//发送非空包也可以
 73                 }
 74             } catch (IOException e) {
 75                 e.printStackTrace();
 76             }
 77         }
 78     });
 79     
 80     /**
 81      * @param args
 82      */
 83     public static void main(String[] args) {
 84         System.out.println("==============SOCKET 客户端===============");
 85         
 86         try {
 87             connect();
 88             tRecv.start() ;
 89         } catch (UnknownHostException e) {
 90             e.printStackTrace();
 91         } catch (IOException e) {
 92             e.printStackTrace();
 93         }
 94         
 95     }
 96     
 97     public static void connect() throws UnknownHostException, IOException  {
 98         client = threadConnect.get();
 99         if(client == null){
100             client = new Socket(HOST, PORT);
101             threadConnect.set(client);
102             tKeep.start();//启动长连接心跳保活线程
103             tSend.start() ;
104 //          System.out.println("========链接开始!========");
105         }
106         outStr = client.getOutputStream();
107         inStr = client.getInputStream();
108     }
109     
110 }
原文地址:https://www.cnblogs.com/hi-gdl/p/8384861.html