Java Socket 一次连接无限次交互数据,while实现,2020-09-10

原理: Socket是对TCP连接的封装,TCP本身就是支持长连接交互的。   在Socket两端都持有一个输出流、输入流, 保持流不被关闭,且相互监听对方的输出,即实现保持长连接交互数据。

 

以下为实现代码。

注意两点
1.双方数据是通过流模式传输,多次交互场景下,流模式没办法判断哪里为单次交互的结束,所以手动设定标识 “over”为单次交互的结束。
2.不要关闭流,让其保持连接,推送数据使用flush();

服务端代码

package com.heiniao.springioc.socket;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class Service {

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(9898);

        while(true) {
            Socket socket = server.accept();
            new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                            try {
                                while(true) {
                                    InputStream inputStream =  socket.getInputStream();
                                    byte[] b = new byte[1024];
                                    int len;
                                    StringBuffer sb = new StringBuffer();
                                    //一次交互完成后,while循环过来,在此阻塞,即监听
                                    while ((len = inputStream.read(b)) != -1) {
                                        sb.append(new String(b, 0, len));
                                        //单次交互结束标识,跳出监听
                                        if(new String(b, 0, len).indexOf("over")>=0){
                                            break;
                                        }
                                    }
                                    String content = sb.toString();
                                    System.out.println("接收到客户端消息" + content.substring(0,content.length()-4));

                                    //往客户端发送数据
                                    long nowtime = (new Date()).getTime();
                                    socket.getOutputStream().write((nowtime+"over").getBytes("UTF-8"));
                                    socket.getOutputStream().flush();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
            ).start();
        }
    }
}

 

客户端代码:

package com.heiniao.springioc.socket;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket = new Socket("127.0.0.1",9898);
        int reqCount =0;
        while(true) {
            socket.getOutputStream().write(("请求时间第"+reqCount+++"次over").getBytes("UTF-8"));
            socket.getOutputStream().flush();

            //流模式下只要不关闭,就可以反复持有,获取数据。  输入流还是那个。
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int len;
            StringBuilder sb = new StringBuilder();
            //一次交互完成后,while循环过来,在此阻塞,即监听
            while ((len = inputStream.read(bytes)) != -1) {
                sb.append(new String(bytes, 0, len));
                //单次交互结束标识,跳出监听
                if(new String(bytes, 0, len).indexOf("over")>=0){
                    break;
                }
            }
            System.out.println("服务端返回的消息: " +  sb.toString().substring(0,sb.toString().length()-4));
            Thread.sleep(2000);
        }
    }
}

 


版权声明:本文为yi_shen_zhi_nu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。