原理: 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版权协议,转载请附上原文出处链接和本声明。