长连接主要用于在少数客户端与服务端的频繁通信,因为这时候如果用短连接频繁通信常会发生Socket出错,并且频繁创建Socket连接也是对资源的浪费
简单说,如果是频繁通讯,使用长连接
长:connect连上后不断开,进行N次收发操作。
短:每次都connect,完成任务后立即断开。下次重连。
一般都是accept后启动一个线程去处理,该线程中的处理大致如下
短连接:
run(){
read //读取请求包
process //处理
write //应答处理结果
}
长连接:
run(){
while(NotEnd){
read
process
write
}
}
SocketClient.java
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.CharBuffer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class SocketClient {
public static final Object locked = new Object();
public static final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(
1024 * 100);
class SendThread extends Thread{
private Socket socket;
public SendThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
while(true){
try {
String send = getSend();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
pw.write(send);
pw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public String getSend() throws InterruptedException{
Thread.sleep(1000);
return "<SOAP-ENV:Envelope>"+System.currentTimeMillis()+"</SOAP-ENV:Envelope>";
}
}
class ReceiveThread extends Thread{
private Socket socket;
public ReceiveThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
while(true){
try {
Reader reader = new InputStreamReader(socket.getInputStream());
CharBuffer charBuffer = CharBuffer.allocate(8192);
int index = -1;
while((index=reader.read(charBuffer))!=-1){
charBuffer.flip();
System.out.println("client:"+charBuffer.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void start() throws UnknownHostException, IOException{
Socket socket = new Socket("10.10.148.40",18889);
new SendThread(socket).start();
new ReceiveThread(socket).start();
}
public static void main(String[] args) throws UnknownHostException, IOException {
new SocketClient().start();
}
}
SocketServer.java
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.CharBuffer;
import java.util.Date;
public class SocketServer {
private final static String SOAP_BEGIN = "<SOAP-ENV:Envelope";
private final static String SOAP_END = "</SOAP-ENV:Envelope>";
public static void main(String[] args) throws IOException {
SocketServer socketServer = new SocketServer();
socketServer.start();
}
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(18889);
while (true) {
Socket socket = serverSocket.accept();
new SocketThread(socket).start();
}
}
class SocketThread extends Thread {
private Socket socket;
private String temp;
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
public SocketThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
Reader reader = new InputStreamReader(socket.getInputStream());
Writer writer = new PrintWriter(new OutputStreamWriter(socket
.getOutputStream(), "GBK"));
CharBuffer charBuffer = CharBuffer.allocate(8192);
int readIndex = -1;
while ((readIndex = reader.read(charBuffer)) != -1) {
charBuffer.flip();
temp += charBuffer.toString();
if (temp.indexOf(SOAP_BEGIN) != -1
&& temp.indexOf(SOAP_END) != -1) {
// 传送一个soap报文
System.out.println(new Date().toLocaleString()+"server:"+temp);
temp="";
writer.write("receive the soap message");
writer.flush();
} else if (temp.indexOf(SOAP_BEGIN) != -1) {
// 包含开始,但不包含
temp = temp.substring(temp.indexOf(SOAP_BEGIN));
}
if (temp.length() > 1024 * 16) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (socket != null) {
if (!socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
分享到:
相关推荐
java socket长连接,支持一个服务器向多个客户端推送消息; 客户端和服务端互相监听,每一个一个客户端断开服务端都有监听。客户端和服务端都做了封装,调用简单。数据通信使用Gson,bean和json互转
java socket 的长连接实例,服务器端支持多个客户端连接,服务器端支持客户端的掉线检测。多线程编程
Java实现Socket长连接和短连接,实现原理可参见个人博客
java socket长连接客户端服务端(标准实例),准确无误,流行结构。
Socket长连接+心跳包+发送+读取,用到的全在这里了,自己看看哪里不需要的就不要添加了!代码很清晰很明白了!
1. 满足具有Socket客户端需求的基本应用. 2. 满足具有Socket服务端的基本应用. 具备并发能力, 能满足可设定个数客户端连接. 参考个人博客: http://blog.csdn.net/ostrichmyself/article/details/6618349
java异步长连接的demo 需要的童鞋可以参考下
Socket长连接、通信、心跳包、消息回调、Java服务端
socket服务器 eclipse tomcat 适合没有接触过搭建服务器的新手。 简单的介绍怎么搭建一个java socket长连接服务器,创建一个demo,怎么发布到云服务器上。
NULL 博文链接:https://516100981.iteye.com/blog/2314314
自己写的Java的socket长连接实例 已测试
客户端的请求首先会进入请求队列,处理器线程池会向请求队列获取请求并且分配分配处理器,每个处理器分配一个线程。处理器可以指定interceptor,处理逻辑都实现在ResponseHandler中。空闲时,处理器线程会休眠直到有...
socket 长连接 简单例子,适合初学的朋友,里面有多线程 实现的,包括心跳包,数据分为两部分传送,首先双方约定用一个4字节的数组告诉对方要传送数据的长度,然后在写入数据,这样长连接的时候,双方可以知道对方...
主要介绍了java socket长连接中解决read阻塞的3个办法,本文取了折中的一个方法,并给出代码实例,需要的朋友可以参考下
java写的socket客户端,能实现接收服务器端数据,发送数据到服务器端,断线自动重连
java Socket连接简单案例
一个socket池 模拟处理并发服务器